diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2022-08-10 10:04:06 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-10 10:04:06 -0400 |
| commit | 1378fffd9da094beb41b2db89b96f556c23ab6cb (patch) | |
| tree | e0558c031bd4b1a013dc56b75c4caa3ff5442021 | |
| parent | 89083c4b50af8e48e70b25b63cc62aca21ab706c (diff) | |
Artifact and ICastable (#2351)
* #include an absolute path didn't work - because paths were taken to always be relative.
* WIP with hierarchical enums.
* Some small fixes and improvements around artifact desc related types.
* Improvements around hierarchical enum.
* Fixes to get Artifact types refactor to be able to execute tests.
* Attempt to better categorize PTX.
* Work around for potentially unused function warning.
* Typo fix.
* Simplify Artifact header.
* Small improvements around Artifact kind/payload/style.
* Added IDestroyable/ICastable
* Add IArtifactList.
* First impl of IArtifactUtil.
* Use the ICastable interface for IArtifactRepresentation.
* Added IArtifactRepresentation & IArtifactAssociated.
* Add SLANG_OVERRIDE to avoid gcc/clang warning.
* Fix calling convention issue on win32.
* Fix missing SLANG_OVERRIDE.
* First attempt at file abstraction around Artifact.
* Added creation of lock file.
* Move functionality for determining file paths to the IArtifactUtil.
Add casting to ICastable.
* Added some casting/finding mechanisms.
* Simplify IArtifact interface, and use Items for file reps.
* Fix problem with libraries on DXIL.
* Split out ArtifactRepresentation.
* Move ArtifactDesc functionality to ArtifactDescUtil. ArtifactInfoUtil becomes ArtifactDescUtil.
* Split implementations from the interfaces for Artifact.
* Use TypeTextUtil for target name outputting.
* Add artifact impls.
* Add ICastableList
* Added UnknownCastableAdapter
* Make ISlangSharedLibrary derive from ICastable, and remain backwards compatible with slang-llvm.
* Refactor Representation on Artifact.
* Make our ISlangBlobs also derive from ICastable.
Make ISlangBlob atomic ref counted.
* Fix typo.
32 files changed, 980 insertions, 312 deletions
@@ -942,6 +942,19 @@ extern "C" }; #define SLANG_UUID_ISlangUnknown ISlangUnknown::getTypeGuid() + + /* An interface to provide a mechanism to cast, that doesn't require ref counting + and doesn't have to return a pointer to a ISlangUnknown derived class */ + class ICastable : public ISlangUnknown + { + SLANG_COM_INTERFACE(0x87ede0e1, 0x4852, 0x44b0, { 0x8b, 0xf2, 0xcb, 0x31, 0x87, 0x4d, 0xe2, 0x39 }); + + /// Can be used to cast to interfaces without reference counting. + /// Also provides access to internal implementations, when they provide a guid + /// Can simulate a 'generated' interface as long as kept in scope by cast from. + virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) = 0; + }; + /** A "blob" of binary data. This interface definition is compatible with the `ID3DBlob` and `ID3D10Blob` interfaces. @@ -992,23 +1005,34 @@ extern "C" typedef void(*SlangFuncPtr)(void); - /** An interface that can be used to encapsulate access to a shared library. An implementation - does not have to implement the library as a shared library. + /** + (DEPRECIATED) ISlangSharedLibrary */ - struct ISlangSharedLibrary: public ISlangUnknown + struct ISlangSharedLibrary_Dep1: public ISlangUnknown { SLANG_COM_INTERFACE( 0x9c9d5bc5, 0xeb61, 0x496f,{ 0x80, 0xd7, 0xd1, 0x47, 0xc4, 0xa2, 0x37, 0x30 }) - /** Get a function by name. If the library is unloaded will only return nullptr. - @param name The name of the function - @return The function pointer related to the name or nullptr if not found - */ + virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) = 0; + }; + #define SLANG_UUID_ISlangSharedLibrary_Dep1 ISlangSharedLibrary_Dep1::getTypeGuid() + + /** An interface that can be used to encapsulate access to a shared library. An implementation + does not have to implement the library as a shared library + */ + struct ISlangSharedLibrary : public ICastable + { + SLANG_COM_INTERFACE(0x70dbc7c4, 0xdc3b, 0x4a07, { 0xae, 0x7e, 0x75, 0x2a, 0xf6, 0xa8, 0x15, 0x55 }) + + /** Get a function by name. If the library is unloaded will only return nullptr. + @param name The name of the function + @return The function pointer related to the name or nullptr if not found + */ SLANG_FORCE_INLINE SlangFuncPtr findFuncByName(char const* name) { return (SlangFuncPtr)findSymbolAddressByName(name); } - /** Get a symbol by name. If the library is unloaded will only return nullptr. - @param name The name of the symbol - @return The pointer related to the name or nullptr if not found - */ + /** Get a symbol by name. If the library is unloaded will only return nullptr. + @param name The name of the symbol + @return The pointer related to the name or nullptr if not found + */ virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) = 0; }; #define SLANG_UUID_ISlangSharedLibrary ISlangSharedLibrary::getTypeGuid() diff --git a/source/compiler-core/slang-artifact-desc-util.cpp b/source/compiler-core/slang-artifact-desc-util.cpp index e382ca08c..413858c32 100644 --- a/source/compiler-core/slang-artifact-desc-util.cpp +++ b/source/compiler-core/slang-artifact-desc-util.cpp @@ -618,7 +618,7 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des /* static */String ArtifactDescUtil::getBaseName(IArtifact* artifact) { - if (auto fileRep = findItem<IFileArtifactRepresentation>(artifact)) + if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact)) { return getBaseName(artifact->getDesc(), fileRep); } @@ -634,7 +634,7 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des /* static */String ArtifactDescUtil::getParentPath(IArtifact* artifact) { - if (auto fileRep = findItem<IFileArtifactRepresentation>(artifact)) + if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact)) { return getParentPath(fileRep); } diff --git a/source/compiler-core/slang-artifact-impl.cpp b/source/compiler-core/slang-artifact-impl.cpp index 8dbae063b..d57edd2c8 100644 --- a/source/compiler-core/slang-artifact-impl.cpp +++ b/source/compiler-core/slang-artifact-impl.cpp @@ -7,6 +7,367 @@ namespace Slang { +/* +If we use LazyCastableList for Items, it means we'll have to use the +UnknownCastableAdapter for ISharedLibrary, IBlob etc. + +That means when we look for an item in the list, we will always do a query interface on those types, +although it will always fail (so no atomic ref count). + +That doesn't seem wholey unreasonable. + +Note that we *can* derive from ICastable for *our* implementations of ISlangBlob, ISharedLibrary. So the +kludge is only needed for types that really do require adaption. For Blob we'll require multiple interface inheritance. +*/ + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! LazyCastableList !!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +void LazyCastableList::removeAt(Index index) +{ + SLANG_ASSERT(index >= 0 && index < getCount()); + + if (auto list = as<ICastableList>(m_castable)) + { + list->removeAt(index); + } + else + { + SLANG_ASSERT(index == 0); + m_castable.setNull(); + } +} + +void LazyCastableList::clear() +{ + if (m_castable) + { + if (auto list = as<ICastableList>(m_castable)) + { + list->clear(); + } + else + { + m_castable.setNull(); + } + } +} + +void LazyCastableList::clearAndDeallocate() +{ + m_castable.setNull(); +} + +Count LazyCastableList::getCount() const +{ + if (m_castable) + { + if (auto list = as<ICastableList>(m_castable)) + { + return list->getCount(); + } + return 1; + } + return 0; +} + +void LazyCastableList::add(ICastable* castable) +{ + SLANG_ASSERT(castable); + SLANG_ASSERT(castable != m_castable); + + if (m_castable) + { + if (auto list = as<ICastableList>(m_castable)) + { + // Shouldn't be in the list + SLANG_ASSERT(list->indexOf(castable) < 0); + list->add(castable); + } + else + { + list = new CastableList; + list->add(m_castable); + m_castable = list; + list->add(castable); + } + } + else + { + m_castable = castable; + } +} + +ICastableList* LazyCastableList::requireList() +{ + if (m_castable) + { + if (auto list = as<ICastableList>(m_castable)) + { + return list; + } + else + { + // Promote to a list with the element in it + list = new CastableList; + list->add(m_castable); + m_castable = list; + return list; + } + } + else + { + // Create an empty list + ICastableList* list = new CastableList; + m_castable = list; + return list; + } +} + +ICastableList* LazyCastableList::getList() +{ + return (m_castable == nullptr) ? nullptr : requireList(); +} + +void* LazyCastableList::find(const Guid& guid) +{ + if (!m_castable) + { + return nullptr; + } + if (auto list = as<ICastableList>(m_castable)) + { + return list->find(guid); + } + else + { + return m_castable->castAs(guid); + } +} + +ConstArrayView<ICastable*> LazyCastableList::getView() const +{ + if (!m_castable) + { + // Empty + return ConstArrayView<ICastable*>(); + } + + if (auto list = as<ICastableList>(m_castable)) + { + const auto count = list->getCount(); + const auto buffer = list->getBuffer(); + + return ConstArrayView<ICastable*>(buffer, count); + } + else + { + return ConstArrayView<ICastable*>((ICastable*const*)&m_castable, 1); + } +} + +Index LazyCastableList::indexOf(ICastable* castable) const +{ + return getView().indexOf(castable); +} + +Index LazyCastableList::indexOfUnknown(ISlangUnknown* unk) const +{ + { + ComPtr<ICastable> castable; + if (SLANG_SUCCEEDED(unk->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable) + { + return indexOf(castable); + } + } + + // It's not derived from ICastable, so can only be in list via an adapter + const auto view = getView(); + + const Count count = view.getCount(); + for (Index i = 0; i < count; ++i) + { + auto adapter = as<IUnknownCastableAdapter>(view[i]); + if (adapter && adapter->getContained() == unk) + { + return i; + } + } + + return -1; +} + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! UnknownCastableAdapter !!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +void* UnknownCastableAdapter::castAs(const Guid& guid) +{ + if (auto intf = getInterface(guid)) + { + return intf; + } + if (auto obj = getObject(guid)) + { + return obj; + } + + if (m_found && guid == m_foundGuid) + { + return m_found; + } + + ComPtr<ISlangUnknown> cast; + if (SLANG_SUCCEEDED(m_contained->queryInterface(guid, (void**)cast.writeRef())) && cast) + { + // Save the interface in the cache + m_found = cast; + m_foundGuid = guid; + + return cast; + } + return nullptr; +} + +void* UnknownCastableAdapter::getInterface(const Guid& guid) +{ + if (guid == ISlangUnknown::getTypeGuid() || + guid == ICastable::getTypeGuid()) + { + return static_cast<ICastable*>(this); + } + return nullptr; +} + +void* UnknownCastableAdapter::getObject(const Guid& guid) +{ + SLANG_UNUSED(guid); + return nullptr; +} + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CastableList !!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +CastableList::~CastableList() +{ + for (auto castable : m_list) + { + castable->release(); + } +} + +void* CastableList::castAs(const Guid& guid) +{ + if (auto intf = getInterface(guid)) + { + return intf; + } + return getObject(guid); +} + +void* CastableList::getInterface(const Guid& guid) +{ + if (guid == ISlangUnknown::getTypeGuid() || + guid == ICastable::getTypeGuid() || + guid == ICastableList::getTypeGuid()) + { + return static_cast<ICastableList*>(this); + } + return nullptr; +} + +void* CastableList::getObject(const Guid& guid) +{ + SLANG_UNUSED(guid); + return nullptr; +} + +void* CastableList::find(const Guid& guid) +{ + for (ICastable* castable : m_list) + { + if (auto ptr = castable->castAs(guid)) + { + return ptr; + } + } + return nullptr; +} + +Index CastableList::indexOf(ICastable* castable) +{ + const Count count = m_list.getCount(); + for (Index i = 0; i < count; ++i) + { + ICastable* cur = m_list[i]; + if (cur == castable) + { + return i; + } + } + return -1; +} + +void CastableList::add(ICastable* castable) +{ + SLANG_ASSERT(castable); + castable->addRef(); + m_list.add(castable); +} + +void CastableList::removeAt(Index i) +{ + auto castable = m_list[i]; + m_list.removeAt(i); + castable->release(); +} + +void CastableList::clear() +{ + for (auto castable : m_list) + { + castable->release(); + } + m_list.clear(); +} + +void CastableList::addUnknown(ISlangUnknown* unk) +{ + // If it has ICastable interface we can just add as that + { + ComPtr<ICastable> castable; + if (SLANG_SUCCEEDED(unk->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable) + { + return add(castable); + } + } + + // Wrap it in an adapter + IUnknownCastableAdapter* adapter = new UnknownCastableAdapter(unk); + add(adapter); +} + +Index CastableList::indexOfUnknown(ISlangUnknown* unk) +{ + SLANG_ASSERT(unk); + // If it has a castable interface we can just look for that + { + ComPtr<ICastable> castable; + if (SLANG_SUCCEEDED(unk->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable) + { + return indexOf(castable); + } + } + + // It's not derived from ICastable, so can only be in list via an adapter + const Count count = m_list.getCount(); + for (Index i = 0; i < count; ++i) + { + auto adapter = as<IUnknownCastableAdapter>(m_list[i]); + if (adapter && adapter->getContained() == unk) + { + return i; + } + } + return -1; +} + /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactList !!!!!!!!!!!!!!!!!!!!!!!!!!! */ void* ArtifactList::getInterface(const Guid& guid) @@ -91,86 +452,24 @@ void* Artifact::getInterface(const Guid& uuid) bool Artifact::exists() { - for (ISlangUnknown* item : m_items) + for (auto rep : m_representations.getView()) { - ComPtr<ICastable> castable; - - if (SLANG_SUCCEEDED(item->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable) + if (auto artifactRep = as<IArtifactRepresentation>(rep)) { - auto rep = as<IArtifactRepresentation>(castable); - if (rep) + // It is an artifact rep and it exists, we are done + if (artifactRep->exists()) { - // It is a rep and it exists - if (rep->exists()) - { - return true; - } - continue; - } - // Associated types don't encapsulate an artifact representation, so don't signal existance - if (as<IArtifactAssociated>(castable)) - { - continue; + return true; } } - - // It can't be IArtifactRepresentation or IArtifactAssociated, so we assume means it exists - return true; - } - - return false; -} - -void Artifact::addItem(ISlangUnknown* intf) -{ - SLANG_ASSERT(intf); - // Can't already be in there - SLANG_ASSERT(m_items.indexOf(intf) < 0); - // Add it - m_items.add(ComPtr<ISlangUnknown>(intf)); -} - -void Artifact::removeItemAt(Index i) -{ - m_items.removeAt(i); -} - -void* Artifact::findItemInterface(const Guid& guid) -{ - for (ISlangUnknown* intf : m_items) - { - ISlangUnknown* cast = nullptr; - if (SLANG_SUCCEEDED(intf->queryInterface(guid, (void**)&cast)) && cast) + else { - // NOTE! This assumes we *DONT* need to ref count to keep an interface in scope - // (as strict COM requires so as to allow on demand interfaces). - cast->release(); - return cast; + // If it's *not* IArtifactRepresentation derived, it's existance *is* a representation + return true; } } - return nullptr; -} - -void* Artifact::findItemObject(const Guid& classGuid) -{ - for (ISlangUnknown* intf : m_items) - { - ComPtr<ICastable> castable; - if (SLANG_SUCCEEDED(intf->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable) - { - void* obj = castable->castAs(classGuid); - // NOTE! This assumes we *DONT* need to ref count to keep an interface in scope - // (as strict COM requires so as to allow on demand interfaces). - - // If could cast return the result - if (obj) - { - return obj; - } - } - } - return nullptr; + return false; } SlangResult Artifact::requireFile(Keep keep, IFileArtifactRepresentation** outFileRep) @@ -182,7 +481,7 @@ SlangResult Artifact::requireFile(Keep keep, IFileArtifactRepresentation** outFi SlangResult Artifact::loadBlob(Keep keep, ISlangBlob** outBlob) { // If we have a blob just return it - if (auto blob = findItem<ISlangBlob>(this)) + if (auto blob = (ISlangBlob*)findRepresentation(ISlangBlob::getTypeGuid())) { blob->addRef(); *outBlob = blob; @@ -192,12 +491,11 @@ SlangResult Artifact::loadBlob(Keep keep, ISlangBlob** outBlob) ComPtr<ISlangBlob> blob; // Look for a representation that we can serialize into a blob - for (ISlangUnknown* intf : m_items) + for (auto rep : m_representations.getView()) { - ComPtr<IArtifactRepresentation> rep; - if (SLANG_SUCCEEDED(intf->queryInterface(IArtifactRepresentation::getTypeGuid(), (void**)rep.writeRef())) && rep) + if (auto artifactRep = as<IArtifactRepresentation>(rep)) { - SlangResult res = rep->writeToBlob(blob.writeRef()); + SlangResult res = artifactRep->writeToBlob(blob.writeRef()); if (SLANG_SUCCEEDED(res) && blob) { break; @@ -214,11 +512,74 @@ SlangResult Artifact::loadBlob(Keep keep, ISlangBlob** outBlob) // Put in cache if (canKeep(keep)) { - addItem(blob); + addRepresentationUnknown(blob); } *outBlob = blob.detach(); return SLANG_OK; } +void Artifact::addAssociated(ICastable* castable) +{ + SLANG_ASSERT(castable); + m_associated.add(castable); +} + +void* Artifact::findAssociated(const Guid& guid) +{ + return m_associated.find(guid); +} + +ICastableList* Artifact::getAssociated() +{ + return m_associated.requireList(); +} + +void Artifact::addRepresentation(IArtifactRepresentation* rep) +{ + SLANG_ASSERT(rep); + if (m_representations.indexOf(rep) >= 0) + { + SLANG_ASSERT_FAILURE("Already have this representation"); + return; + } + m_representations.add(rep); +} + +void Artifact::addRepresentationUnknown(ISlangUnknown* unk) +{ + SLANG_ASSERT(unk); + if (m_representations.indexOfUnknown(unk) >= 0) + { + SLANG_ASSERT_FAILURE("Already have this representation"); + return; + } + + ComPtr<ICastable> castable; + if (SLANG_SUCCEEDED(unk->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable) + { + if (m_representations.indexOf(castable) >= 0) + { + SLANG_ASSERT_FAILURE("Already have this representation"); + return; + } + m_representations.add(castable); + } + else + { + UnknownCastableAdapter* adapter = new UnknownCastableAdapter(unk); + m_representations.add(adapter); + } +} + +void* Artifact::findRepresentation(const Guid& guid) +{ + return m_representations.find(guid); +} + +ICastableList* Artifact::getRepresentations() +{ + return m_representations.requireList(); +} + } // namespace Slang diff --git a/source/compiler-core/slang-artifact-impl.h b/source/compiler-core/slang-artifact-impl.h index 35dbe5f98..79aad3b64 100644 --- a/source/compiler-core/slang-artifact-impl.h +++ b/source/compiler-core/slang-artifact-impl.h @@ -12,6 +12,89 @@ namespace Slang { +/* An adapter such that types which aren't derived from ICastable, can be used as such. + +With the following caveats. +* the interfaces/objects of the adapter are checked *first*, so IUnknown will always be for the adapter +* assumes when doing a queryInterface on the contained item +*/ +class UnknownCastableAdapter : public ComBaseObject, public IUnknownCastableAdapter +{ +public: + SLANG_COM_BASE_IUNKNOWN_ALL + + // ICastable + SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE; + + // IUnknownCastableAdapter + virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getContained() SLANG_OVERRIDE { return m_contained; } + + UnknownCastableAdapter(ISlangUnknown* unk): + m_contained(unk) + { + SLANG_ASSERT(unk); + } + +protected: + void* getInterface(const Guid& guid); + void* getObject(const Guid& guid); + + ComPtr<ISlangUnknown> m_contained; + + // We hold a cache for a single lookup to make things a little faster + void* m_found = nullptr; + Guid m_foundGuid; +}; + +class CastableList : public ComBaseObject, public ICastableList +{ +public: + SLANG_COM_BASE_IUNKNOWN_ALL + + // ICastable + SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE; + + // ICastableList + virtual Count SLANG_MCALL getCount() SLANG_OVERRIDE { return m_list.getCount(); } + virtual ICastable* SLANG_MCALL getAt(Index i) SLANG_OVERRIDE { return m_list[i]; } + virtual void SLANG_MCALL add(ICastable* castable) SLANG_OVERRIDE; + virtual void SLANG_MCALL addUnknown(ISlangUnknown* unk) SLANG_OVERRIDE; + virtual void SLANG_MCALL removeAt(Index i) SLANG_OVERRIDE; + virtual void SLANG_MCALL clear() SLANG_OVERRIDE; + virtual Index SLANG_MCALL indexOf(ICastable* castable) SLANG_OVERRIDE; + virtual Index SLANG_MCALL indexOfUnknown(ISlangUnknown* unk) SLANG_OVERRIDE; + virtual void* SLANG_MCALL find(const Guid& guid) SLANG_OVERRIDE; + virtual ICastable* const* SLANG_MCALL getBuffer() SLANG_OVERRIDE { return m_list.getBuffer(); } + + virtual ~CastableList(); + +protected: + void* getInterface(const Guid& guid); + void* getObject(const Guid& guid); + + List<ICastable*> m_list; +}; + +class LazyCastableList +{ +public: + void add(ICastable* castable); + Count getCount() const; + void removeAt(Index index); + void clear(); + void clearAndDeallocate(); + void* find(const Guid& guid); + ConstArrayView<ICastable*> getView() const; + Index indexOf(ICastable* castable) const; + Index indexOfUnknown(ISlangUnknown* unk) const; + + ICastableList* requireList(); + ICastableList* getList(); + +protected: + ComPtr<ICastable> m_castable; +}; + class ArtifactList : public ComBaseObject, public IArtifactList { public: @@ -86,12 +169,15 @@ public: virtual SLANG_NO_THROW SlangResult SLANG_MCALL loadBlob(Keep keep, ISlangBlob** outBlob) SLANG_OVERRIDE; virtual SLANG_NO_THROW SlangResult SLANG_MCALL requireFile(Keep keep, IFileArtifactRepresentation** outFileRep) SLANG_OVERRIDE; virtual SLANG_NO_THROW const char* SLANG_MCALL getName() SLANG_OVERRIDE { return m_name.getBuffer(); } - virtual SLANG_NO_THROW void* SLANG_MCALL findItemInterface(const Guid& uuid) SLANG_OVERRIDE; - virtual SLANG_NO_THROW void* SLANG_MCALL findItemObject(const Guid& classGuid) SLANG_OVERRIDE; - virtual SLANG_NO_THROW void SLANG_MCALL addItem(ISlangUnknown* intf) SLANG_OVERRIDE; - virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getItemAt(Index i) SLANG_OVERRIDE { return m_items[i]; } - virtual SLANG_NO_THROW void SLANG_MCALL removeItemAt(Index i) SLANG_OVERRIDE; - virtual SLANG_NO_THROW Index SLANG_MCALL getItemCount() SLANG_OVERRIDE { return m_items.getCount(); } + + virtual SLANG_NO_THROW void SLANG_MCALL addAssociated(ICastable* castable) SLANG_OVERRIDE; + virtual void* SLANG_MCALL SLANG_MCALL findAssociated(const Guid& unk) SLANG_OVERRIDE; + virtual ICastableList* SLANG_MCALL getAssociated() SLANG_OVERRIDE; + + virtual SLANG_NO_THROW void SLANG_MCALL addRepresentation(IArtifactRepresentation* rep) SLANG_OVERRIDE; + virtual SLANG_NO_THROW void SLANG_MCALL addRepresentationUnknown(ISlangUnknown* rep) SLANG_OVERRIDE; + virtual void* SLANG_MCALL SLANG_MCALL findRepresentation(const Guid& guid) SLANG_OVERRIDE; + virtual ICastableList* SLANG_MCALL getRepresentations() SLANG_OVERRIDE; /// Ctor Artifact(const Desc& desc, const String& name) : @@ -108,7 +194,10 @@ protected: String m_name; ///< Name of this artifact - List<ComPtr<ISlangUnknown>> m_items; ///< Associated items + LazyCastableList m_associated; ///< Associated items + LazyCastableList m_representations; ///< Representations + + ComPtr<IArtifactList> m_children; ///< The children to this artifact }; } // namespace Slang diff --git a/source/compiler-core/slang-artifact-util.cpp b/source/compiler-core/slang-artifact-util.cpp index 9a8194969..7f69a0464 100644 --- a/source/compiler-core/slang-artifact-util.cpp +++ b/source/compiler-core/slang-artifact-util.cpp @@ -93,20 +93,16 @@ SlangResult ArtifactUtilImpl::createLockFile(const char* inNameBase, ISlangMutab SlangResult ArtifactUtilImpl::calcArtifactPath(const ArtifactDesc& desc, const char* inBasePath, ISlangBlob** outPath) { UnownedStringSlice basePath(inBasePath); - StringBuilder path; SLANG_RETURN_ON_FAIL(ArtifactDescUtil::calcPathForDesc(desc, basePath, path)); - - auto blob = new StringBlob(path); - blob->addRef(); - *outPath = blob; + *outPath = StringBlob::create(path).detach(); return SLANG_OK; } SlangResult ArtifactUtilImpl::requireFileDefaultImpl(IArtifact* artifact, ArtifactKeep keep, IFileArtifactRepresentation** outFile) { // See if we already have it - if (auto fileRep = findItem<IFileArtifactRepresentation>(artifact)) + if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact)) { fileRep->addRef(); *outFile = fileRep; @@ -143,7 +139,7 @@ SlangResult ArtifactUtilImpl::requireFileDefaultImpl(IArtifact* artifact, Artifa IFileArtifactRepresentation* fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Owned, path, lockFile, nullptr); if (canKeep(keep)) { - artifact->addItem(fileRep); + artifact->addRepresentation(fileRep); } // Return it diff --git a/source/compiler-core/slang-artifact.h b/source/compiler-core/slang-artifact.h index 86b08dbb9..3c991b7b6 100644 --- a/source/compiler-core/slang-artifact.h +++ b/source/compiler-core/slang-artifact.h @@ -201,6 +201,7 @@ inline /* static */ArtifactDesc ArtifactDesc::make(Packed inPacked) // Forward declare class IFileArtifactRepresentation; +class IArtifactRepresentation; // Controls what items can be kept. enum class ArtifactKeep @@ -217,6 +218,40 @@ SLANG_INLINE bool canKeep(ArtifactKeep keep) { return Index(keep) >= Index(Artif /// Returns the keep type for an intermediate SLANG_INLINE ArtifactKeep getIntermediateKeep(ArtifactKeep keep) { return (keep == ArtifactKeep::All) ? ArtifactKeep::All : ArtifactKeep::No; } +/* A useful interface for handling lists of castable interfaces. Cannot hold nullptr */ +class ICastableList : public ICastable +{ + SLANG_COM_INTERFACE(0x335f3d40, 0x934c, 0x40dc, { 0xb5, 0xe1, 0xf7, 0x6e, 0x40, 0x3, 0x62, 0x5 }) + + /// Get the count of all interfaces held in the list + virtual Count SLANG_MCALL getCount() = 0; + /// Get the interface at the specified index + virtual ICastable* SLANG_MCALL getAt(Index i) = 0; + /// Add an item to the list + virtual void SLANG_MCALL add(ICastable* unk) = 0; + /// Add IUnknown, will cast to ICastable and if that's not possible will wrap + virtual void SLANG_MCALL addUnknown(ISlangUnknown* unk) = 0; + /// Remove item at index, remaining items stay in the same order + virtual void SLANG_MCALL removeAt(Index i) = 0; + /// Clear the list + virtual void SLANG_MCALL clear() = 0; + /// Find the first index of castable, or -1 if not found + virtual Index SLANG_MCALL indexOf(ICastable* castable) = 0; + /// Find the index interface (handling wrapping if necessary) + virtual Index SLANG_MCALL indexOfUnknown(ISlangUnknown* unk) = 0; + /// Find the first item that casts to non null + virtual void* SLANG_MCALL find(const Guid& guid) = 0; + /// Access the internal buffer (any mutation can invalidate this value) + virtual ICastable*const* SLANG_MCALL getBuffer() = 0; +}; + +// Simply finding things in a ICastableList +template <typename T> +SLANG_FORCE_INLINE T* find(ICastableList* list) +{ + return reinterpret_cast<T*>(list->find(T::getTypeGuid())); +} + /* The IArtifact interface is designed to represent some Artifact of compilation. It could be input to or output from a compilation. An abstraction is desirable here, because depending on the compiler the artifact/s could be @@ -286,19 +321,22 @@ public: /// Get the name of the artifact. This can be empty. virtual SLANG_NO_THROW const char* SLANG_MCALL getName() = 0; - /// Find an item by casting it's interface - virtual SLANG_NO_THROW void* SLANG_MCALL findItemInterface(const Guid& uuid) = 0; - /// Only works on ICastable derived items. Can find interfaces or objects. - virtual SLANG_NO_THROW void* SLANG_MCALL findItemObject(const Guid& classGuid) = 0; - - /// Add a representation - virtual SLANG_NO_THROW void SLANG_MCALL addItem(ISlangUnknown* item) = 0; - /// Get the item at the index - virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getItemAt(Index i) = 0; - /// Remove the element at the specified index. - virtual SLANG_NO_THROW void SLANG_MCALL removeItemAt(Index i) = 0; - /// Get the amount of elements - virtual SLANG_NO_THROW Index SLANG_MCALL getItemCount() = 0; + /// Add data associated with this artifact + virtual SLANG_NO_THROW void SLANG_MCALL addAssociated(ICastable* castable) = 0; + /// Find an associated item + virtual void* SLANG_MCALL SLANG_MCALL findAssociated(const Guid& unk) = 0; + /// TODO(JS): We may want this to return nullptr if it's empty. + /// Get the list of associated items + virtual ICastableList* SLANG_MCALL getAssociated() = 0; + + /// Add a representation that derives from IArtifactRepresentation + virtual SLANG_NO_THROW void SLANG_MCALL addRepresentation(IArtifactRepresentation* rep) = 0; + /// Add a representation that doesn't derive from IArtifactRepresentation + virtual SLANG_NO_THROW void SLANG_MCALL addRepresentationUnknown(ISlangUnknown* rep) = 0; + /// Find representation + virtual void* SLANG_MCALL SLANG_MCALL findRepresentation(const Guid& guid) = 0; + /// Get the list of all representations + virtual ICastableList* SLANG_MCALL getRepresentations() = 0; }; /* A list of artifacts. */ @@ -336,44 +374,16 @@ class IArtifactRepresentation : public ICastable /// Convert the instance into a serializable blob. /// Returns SLANG_E_NOT_IMPLEMENTED if an implementation doesn't implement - virtual SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** blob) = 0; + virtual SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** blob) = 0; - /// Returns true if this representation exists and is available for use. + /// Returns true if this representation exists and is available for use. virtual SLANG_NO_THROW bool SLANG_MCALL exists() = 0; }; -/* Interface for types that are associated with an artifact, but aren't a representation, or are -only part of a representation. */ -class IArtifactAssociated : public ICastable -{ - SLANG_COM_INTERFACE(0xafc0e4db, 0x16d4, 0x4d7a, { 0x93, 0x5f, 0x3e, 0x47, 0x7a, 0x23, 0x2a, 0x7f }) -}; - - -// Helper template to make finding an item more simple -// There isn't a problem if we only have a forward declaration, because in that case T::getTypeGuid can't work. -SLANG_FORCE_INLINE void* _findItemImpl(IArtifact* artifact, const Guid& guid, const ISlangUnknown* intf) -{ - SLANG_UNUSED(intf); - return artifact->findItemInterface(guid); -} - -SLANG_FORCE_INLINE void* _findItemImpl(IArtifact* artifact, const Guid& guid, const ICastable* castable) -{ - SLANG_UNUSED(castable); - return artifact->findItemObject(guid); -} - -SLANG_FORCE_INLINE void* _findItemImpl(IArtifact* artifact, const Guid& guid, const void* other) -{ - SLANG_UNUSED(other); - return artifact->findItemObject(guid); -} - template <typename T> -SLANG_FORCE_INLINE T* findItem(IArtifact* artifact) +SLANG_FORCE_INLINE T* findRepresentation(IArtifact* artifact) { - return (T*)_findItemImpl(artifact, T::getTypeGuid(), (T*)nullptr); + return reinterpret_cast<T*>(artifact->findRepresentation(T::getTypeGuid())); } } // namespace Slang diff --git a/source/compiler-core/slang-downstream-compiler.cpp b/source/compiler-core/slang-downstream-compiler.cpp index 2e30c23bc..c492b6dd7 100644 --- a/source/compiler-core/slang-downstream-compiler.cpp +++ b/source/compiler-core/slang-downstream-compiler.cpp @@ -387,7 +387,7 @@ SlangResult CommandLineDownstreamCompileResult::getBinary(ComPtr<ISlangBlob>& ou // Read the contents of the binary SLANG_RETURN_ON_FAIL(File::readAllBytes(m_moduleFilePath, contents)); - m_binaryBlob = new ScopeRefObjectBlob(ListBlob::moveCreate(contents), m_temporaryFiles); + m_binaryBlob = ScopeRefObjectBlob::create(ListBlob::moveCreate(contents), m_temporaryFiles); outBlob = m_binaryBlob; return SLANG_OK; } diff --git a/source/compiler-core/slang-glslang-compiler.cpp b/source/compiler-core/slang-glslang-compiler.cpp index fc8beaa48..70743f9d9 100644 --- a/source/compiler-core/slang-glslang-compiler.cpp +++ b/source/compiler-core/slang-glslang-compiler.cpp @@ -205,7 +205,7 @@ SlangResult GlslangDownstreamCompiler::compile(const CompileOptions& options, Re return SLANG_OK; } - RefPtr<ListBlob> spirvBlob = ListBlob::moveCreate(spirv); + ComPtr<ISlangBlob> spirvBlob = ListBlob::moveCreate(spirv); outResult = new BlobDownstreamCompileResult(diagnostics, spirvBlob); return SLANG_OK; diff --git a/source/compiler-core/slang-nvrtc-compiler.cpp b/source/compiler-core/slang-nvrtc-compiler.cpp index 11ef746f6..3f285ada2 100644 --- a/source/compiler-core/slang-nvrtc-compiler.cpp +++ b/source/compiler-core/slang-nvrtc-compiler.cpp @@ -833,7 +833,7 @@ SlangResult NVRTCDownstreamCompiler::compile(const CompileOptions& options, RefP res = m_nvrtcCompileProgram(program, int(dstOptions.getCount()), dstOptions.getBuffer()); - RefPtr<ListBlob> blob; + ComPtr<ISlangBlob> blob; DownstreamDiagnostics diagnostics; diagnostics.result = _asResult(res); diff --git a/source/core/slang-blob.cpp b/source/core/slang-blob.cpp index 569991508..0da8f6292 100644 --- a/source/core/slang-blob.cpp +++ b/source/core/slang-blob.cpp @@ -2,19 +2,76 @@ namespace Slang { +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! BlobBase !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + ISlangUnknown* BlobBase::getInterface(const Guid& guid) { - return (guid == ISlangUnknown::getTypeGuid() || guid == ISlangBlob::getTypeGuid()) ? static_cast<ISlangBlob*>(this) : nullptr; + if (guid == ISlangUnknown::getTypeGuid() || + guid == ISlangBlob::getTypeGuid()) + { + return static_cast<ISlangBlob*>(this); + } + if (guid == ICastable::getTypeGuid()) + { + return static_cast<ICastable*>(this); + } + return nullptr; +} + +void* BlobBase::getObject(const Guid& guid) +{ + SLANG_UNUSED(guid); + return nullptr; } +void* BlobBase::castAs(const SlangUUID& guid) +{ + if (auto intf = getInterface(guid)) + { + return intf; + } + return getObject(guid); +} + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StaticBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + SlangResult StaticBlob::queryInterface(SlangUUID const& guid, void** outObject) { - if (guid == ISlangUnknown::getTypeGuid() || guid == ISlangBlob::getTypeGuid()) + if (auto intf = getInterface(guid)) { - *outObject = static_cast<ISlangBlob*>(this); + *outObject = intf; return SLANG_OK; } return SLANG_E_NO_INTERFACE; } - + +void* StaticBlob::castAs(const SlangUUID& guid) +{ + if (auto intf = getInterface(guid)) + { + return intf; + } + return getObject(guid); +} + +ISlangUnknown* StaticBlob::getInterface(const Guid& guid) +{ + if (guid == ISlangUnknown::getTypeGuid() || + guid == ISlangBlob::getTypeGuid()) + { + return static_cast<ISlangBlob*>(this); + } + if (guid == ICastable::getTypeGuid()) + { + return static_cast<ICastable*>(this); + } + return nullptr; +} + +void* StaticBlob::getObject(const Guid& guid) +{ + SLANG_UNUSED(guid); + return nullptr; +} + } // namespace Slang diff --git a/source/core/slang-blob.h b/source/core/slang-blob.h index 58984471f..b1384bb2c 100644 --- a/source/core/slang-blob.h +++ b/source/core/slang-blob.h @@ -11,22 +11,31 @@ #include "../../slang-com-helper.h" #include "../../slang-com-ptr.h" +#include "../core/slang-com-object.h" + namespace Slang { /** Base class for simple blobs. */ -class BlobBase : public ISlangBlob, public RefObject +class BlobBase : public ISlangBlob, public ICastable, public ComBaseObject { public: // ISlangUnknown - SLANG_REF_OBJECT_IUNKNOWN_ALL + SLANG_COM_BASE_IUNKNOWN_ALL + + // ICastable + virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE; protected: ISlangUnknown* getInterface(const Guid& guid); + void* getObject(const Guid& guid); }; /** A blob that uses a `String` for its storage. NOTE! Returns length *WITHOUT* terminating 0, even though there is one. + +NOTE! Whilst BobBase is atomic ref counted, the contained string *is not*. +There is a reasonable argument that StringBlob should contain it's own copy of the string contents. */ class StringBlob : public BlobBase { @@ -35,14 +44,16 @@ public: SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_string.getBuffer(); } SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_string.getLength(); } - /// Get the contained string - SLANG_FORCE_INLINE const String& getString() const { return m_string; } + static ComPtr<ISlangBlob> create(const String& in) { return ComPtr<ISlangBlob>(new StringBlob(in)); } +protected: explicit StringBlob(String const& string) : m_string(string) {} -protected: + /// Get the contained string + SLANG_FORCE_INLINE const String& getString() const { return m_string; } + String m_string; }; @@ -56,21 +67,20 @@ public: SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data.getBuffer(); } SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_data.getCount(); } - ListBlob() {} + static ComPtr<ISlangBlob> create(const List<uint8_t>& data) { return ComPtr<ISlangBlob>(new ListBlob(data)); } + + static ComPtr<ISlangBlob> moveCreate(List<uint8_t>& data) { return ComPtr<ISlangBlob>(new ListBlob(_Move(data))); } - ListBlob(const List<uint8_t>& data): m_data(data) {} +protected: + explicit ListBlob(const List<uint8_t>& data) : m_data(data) {} // Move ctor - ListBlob(List<uint8_t>&& data): m_data(data) {} + explicit ListBlob(List<uint8_t>&& data) : m_data(data) {} - static RefPtr<ListBlob> moveCreate(List<uint8_t>& data) { return new ListBlob(_Move(data)); } + void operator=(const ThisType& rhs) = delete; List<uint8_t> m_data; - -protected: - void operator=(const ThisType& rhs) = delete; }; - class ScopedAllocation { public: @@ -172,29 +182,35 @@ public: SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data.getData(); } SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_data.getSizeInBytes(); } - // Ctor - // NOTE! Takes a copy of the input data - RawBlob(const void* data, size_t size) - { - memcpy(m_data.allocate(size), data, size); - } - /// Moves ownership of data and dataCount to the blob /// data must be a pointer returned by ::malloc. - static RefPtr<RawBlob> moveCreate(uint8_t* data, size_t dataCount) + static ComPtr<ISlangBlob> moveCreate(uint8_t* data, size_t dataCount) { RawBlob* blob = new RawBlob; blob->m_data.attach(data, dataCount); - return blob; + return ComPtr<ISlangBlob>(blob); } - static RefPtr<RawBlob> moveCreate(ScopedAllocation& alloc) + static ComPtr<ISlangBlob> moveCreate(ScopedAllocation& alloc) { RawBlob* blob = new RawBlob; blob->m_data.swap(alloc); - return blob; + return ComPtr<ISlangBlob>(blob); + } + + /// Create a blob that will retain (a copy of) raw data. + static inline ComPtr<ISlangBlob> create(void const* inData, size_t size) + { + return ComPtr<ISlangBlob>(new RawBlob(inData, size)); } protected: + // Ctor + // NOTE! Takes a copy of the input data + RawBlob(const void* data, size_t size) + { + memcpy(m_data.allocate(size), data, size); + } + RawBlob() = default; ScopedAllocation m_data; @@ -208,14 +224,19 @@ public: SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data; } SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_dataSizeInBytes; } + static inline ComPtr<ISlangBlob> create(void const* inData, size_t size) + { + return ComPtr<ISlangBlob>(new UnownedRawBlob(inData, size)); + } + +protected: // Ctor - UnownedRawBlob(const void* data, size_t size): + UnownedRawBlob(const void* data, size_t size) : m_data(data), m_dataSizeInBytes(size) { } -protected: UnownedRawBlob() = default; const void* m_data; @@ -226,7 +247,7 @@ protected: The memory it references is *not* owned by the blob. This is useful when a Blob is useful to represent some global immutable chunk of memory. */ -class StaticBlob : public ISlangBlob +class StaticBlob : public ISlangBlob, public ICastable { public: @@ -235,6 +256,9 @@ public: SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; } SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; } + // ICastable + virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE; + // ISlangBlob SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_data; } SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_dataCount; } @@ -246,17 +270,13 @@ public: } protected: + ISlangUnknown* getInterface(const Guid& guid); + void* getObject(const Guid& guid); + const void* m_data; size_t m_dataCount; }; -/// Create a blob that will retain (a copy of) raw data. -/// -inline ComPtr<ISlangBlob> createRawBlob(void const* inData, size_t size) -{ - return ComPtr<ISlangBlob>(new RawBlob(inData, size)); -} - class ScopeRefObjectBlob : public BlobBase { public: @@ -264,14 +284,22 @@ public: SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_blob->getBufferPointer(); } SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_blob->getBufferSize(); } + static inline ComPtr<ISlangBlob> create(ISlangBlob* blob, RefObject* scope) + { + return ComPtr<ISlangBlob>(new ScopeRefObjectBlob(blob, scope)); + } + +protected: + // Ctor + ScopeRefObjectBlob(ISlangBlob* blob, RefObject* scope) : m_blob(blob), m_scope(scope) { } -protected: + RefPtr<RefObject> m_scope; ComPtr<ISlangBlob> m_blob; }; diff --git a/source/core/slang-destroyable.h b/source/core/slang-destroyable.h index 343cc2484..bf373ba33 100644 --- a/source/core/slang-destroyable.h +++ b/source/core/slang-destroyable.h @@ -9,16 +9,13 @@ namespace Slang { -/* An interface to provide a mechanism to cast, that doesn't require ref counting -and doesn't have to return a pointer to a ISlangUnknown derived class */ -class ICastable : public ISlangUnknown +/* Adapter interface to make a non castable type work as ICastable */ +class IUnknownCastableAdapter : public ICastable { - SLANG_COM_INTERFACE(0x87ede0e1, 0x4852, 0x44b0, { 0x8b, 0xf2, 0xcb, 0x31, 0x87, 0x4d, 0xe2, 0x39 } ); + SLANG_COM_INTERFACE(0x8b4aad81, 0x4934, 0x4a67, { 0xb2, 0xe2, 0xe9, 0x17, 0xfc, 0x29, 0x12, 0x54 } ); - /// Can be used to cast to interfaces without reference counting. - /// Also provides access to internal implementations, when they provide a guid - /// Can simulate a 'generated' interface as long as kept in scope by cast from. - virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) = 0; + /// When using the adapter, this provides a way to directly get the internal no ICastable type + virtual SLANG_NO_THROW ISlangUnknown* SLANG_MCALL getContained() = 0; }; /* An interface that allows for an object to implement 'destruction'. A destroyed diff --git a/source/core/slang-file-system.cpp b/source/core/slang-file-system.cpp index 52ec40c07..6d9ad4324 100644 --- a/source/core/slang-file-system.cpp +++ b/source/core/slang-file-system.cpp @@ -608,13 +608,14 @@ SlangResult CacheFileSystem::loadFile(char const* pathIn, ISlangBlob** blobOut) SlangResult CacheFileSystem::getFileUniqueIdentity(const char* path, ISlangBlob** outUniqueIdentity) { + *outUniqueIdentity = nullptr; PathInfo* info = _resolvePathCacheInfo(path); - if (!info) + if (!info || info->m_uniqueIdentity.getLength() <= 0) { return SLANG_E_NOT_FOUND; } - info->m_uniqueIdentity->addRef(); - *outUniqueIdentity = info->m_uniqueIdentity; + + *outUniqueIdentity = StringBlob::create(info->m_uniqueIdentity).detach(); return SLANG_OK; } @@ -694,6 +695,8 @@ SlangResult CacheFileSystem::getSimplifiedPath(const char* path, ISlangBlob** ou SlangResult CacheFileSystem::getCanonicalPath(const char* path, ISlangBlob** outCanonicalPath) { + *outCanonicalPath = nullptr; + // A file must exist to get a canonical path... PathInfo* info = _resolvePathCacheInfo(path); if (!info) @@ -716,12 +719,8 @@ SlangResult CacheFileSystem::getCanonicalPath(const char* path, ISlangBlob** out if (SLANG_SUCCEEDED(res)) { // Get the path as a string - String canonicalPath = StringUtil::getString(canonicalPathBlob); - if (canonicalPath.getLength() > 0) - { - info->m_canonicalPath = new StringBlob(canonicalPath); - } - else + info->m_canonicalPath = StringUtil::getString(canonicalPathBlob); + if (info->m_canonicalPath.getLength() <= 0) { res = SLANG_FAIL; } @@ -731,11 +730,12 @@ SlangResult CacheFileSystem::getCanonicalPath(const char* path, ISlangBlob** out info->m_getCanonicalPathResult = toCompressedResult(res); } - if (info->m_canonicalPath) + // Create the blob + if (info->m_canonicalPath.getLength()) { - info->m_canonicalPath->addRef(); + *outCanonicalPath = StringBlob::create(info->m_canonicalPath).detach(); } - *outCanonicalPath = info->m_canonicalPath; + return SLANG_OK; } diff --git a/source/core/slang-file-system.h b/source/core/slang-file-system.h index 8a9cfb811..3df05b6e1 100644 --- a/source/core/slang-file-system.h +++ b/source/core/slang-file-system.h @@ -113,10 +113,9 @@ class CacheFileSystem: public ISlangFileSystemExt, public RefObject struct PathInfo { - PathInfo(const String& uniqueIdentity) + PathInfo(const String& uniqueIdentity): + m_uniqueIdentity(uniqueIdentity) { - m_uniqueIdentity = new StringBlob(uniqueIdentity); - m_loadFileResult = CompressedResult::Uninitialized; m_getPathTypeResult = CompressedResult::Uninitialized; m_getCanonicalPathResult = CompressedResult::Uninitialized; @@ -125,16 +124,16 @@ class CacheFileSystem: public ISlangFileSystemExt, public RefObject } /// Get the unique identity path as a string - const String& getUniqueIdentity() const { SLANG_ASSERT(m_uniqueIdentity); return m_uniqueIdentity->getString(); } + const String& getUniqueIdentity() const { return m_uniqueIdentity; } - RefPtr<StringBlob> m_uniqueIdentity; + String m_uniqueIdentity; CompressedResult m_loadFileResult; CompressedResult m_getPathTypeResult; CompressedResult m_getCanonicalPathResult; SlangPathType m_pathType; ComPtr<ISlangBlob> m_fileBlob; - RefPtr<StringBlob> m_canonicalPath; + String m_canonicalPath; }; Dictionary<String, PathInfo*>& getPathMap() { return m_pathMap; } diff --git a/source/core/slang-riff-file-system.cpp b/source/core/slang-riff-file-system.cpp index d52015fb3..186650ed3 100644 --- a/source/core/slang-riff-file-system.cpp +++ b/source/core/slang-riff-file-system.cpp @@ -215,7 +215,7 @@ SlangResult RiffFileSystem::saveFile(const char* path, const void* data, size_t else { // Just store the data directly. - contents = new RawBlob(data, size); + contents = RawBlob::create(data, size); } Entry* entry = _getEntryFromCanonicalPath(canonicalPath); @@ -376,7 +376,7 @@ SlangResult RiffFileSystem::loadArchive(const void* archive, size_t archiveSizeI } // Get the compressed data - dstEntry->m_contents = new RawBlob(srcData, srcEntry->compressedSize); + dstEntry->m_contents = RawBlob::create(srcData, srcEntry->compressedSize); break; } case SLANG_PATH_TYPE_DIRECTORY: break; @@ -444,10 +444,10 @@ SlangResult RiffFileSystem::storeArchive(bool blobOwnsContent, ISlangBlob** outB // We now write the RiffContainer to the stream SLANG_RETURN_ON_FAIL(RiffUtil::write(container.getRoot(), true, &stream)); - RefPtr<ListBlob> blob = new ListBlob; - stream.swapContents(blob->m_data); + List<uint8_t> data; + stream.swapContents(data); - *outBlob = blob.detach(); + *outBlob = ListBlob::moveCreate(data).detach(); return SLANG_OK; } diff --git a/source/core/slang-shared-library.cpp b/source/core/slang-shared-library.cpp index 6ce10ad9e..0e4f0ee73 100644 --- a/source/core/slang-shared-library.cpp +++ b/source/core/slang-shared-library.cpp @@ -62,7 +62,7 @@ SlangResult DefaultSharedLibraryLoader::loadPlatformSharedLibrary(const char* pa } } -/* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ +/* !!!!!!!!!!!!!!!!!!!!!!!!!! TemporarySharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ TemporarySharedLibrary::~TemporarySharedLibrary() { @@ -76,38 +76,50 @@ TemporarySharedLibrary::~TemporarySharedLibrary() /* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ -SLANG_NO_THROW SlangResult SLANG_MCALL DefaultSharedLibrary::queryInterface(SlangUUID const& uuid, void** outObject) +DefaultSharedLibrary::~DefaultSharedLibrary() { - // Mechanism to cast to underlying type. - // NOTE! Purposefully does not ref count - if (uuid == DefaultSharedLibrary::getTypeGuid()) + if (m_sharedLibraryHandle) { - *outObject = this; - return SLANG_OK; + SharedLibrary::unload(m_sharedLibraryHandle); } +} + +void* DefaultSharedLibrary::findSymbolAddressByName(char const* name) +{ + return SharedLibrary::findSymbolAddressByName(m_sharedLibraryHandle, name); +} - if (uuid == ISlangUnknown::getTypeGuid() || uuid == ISlangSharedLibrary::getTypeGuid()) +void* DefaultSharedLibrary::castAs(const SlangUUID& guid) +{ + if (auto intf = getInterface(guid)) { - ++m_refCount; - *outObject = static_cast<ISlangSharedLibrary*>(this); - return SLANG_OK; + return intf; } - return SLANG_E_NO_INTERFACE; + return getObject(guid); } -DefaultSharedLibrary::~DefaultSharedLibrary() +void* DefaultSharedLibrary::getInterface(const Guid& guid) { - if (m_sharedLibraryHandle) + if (guid == ISlangUnknown::getTypeGuid() || + guid == ICastable::getTypeGuid() || + guid == ISlangSharedLibrary::getTypeGuid()) { - SharedLibrary::unload(m_sharedLibraryHandle); + return static_cast<ISlangSharedLibrary*>(this); } + return nullptr; } -void* DefaultSharedLibrary::findSymbolAddressByName(char const* name) +void* DefaultSharedLibrary::getObject(const Guid& guid) { - return SharedLibrary::findSymbolAddressByName(m_sharedLibraryHandle, name); + if (guid == DefaultSharedLibrary::getTypeGuid()) + { + return this; + } + return nullptr; } +/* !!!!!!!!!!!!!!!!!!!!!!!!!! SharedLibraryUtils !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ + String SharedLibraryUtils::getSharedLibraryFileName(void* symbolInLib) { #if defined(_WIN32) diff --git a/source/core/slang-shared-library.h b/source/core/slang-shared-library.h index 44adb1ac6..c0074bad3 100644 --- a/source/core/slang-shared-library.h +++ b/source/core/slang-shared-library.h @@ -52,10 +52,9 @@ class DefaultSharedLibrary : public ISlangSharedLibrary, public ComBaseObject SLANG_CLASS_GUID(0xe7f2597b, 0xf803, 0x4b6e, { 0xaf, 0x8b, 0xcb, 0xe3, 0xa2, 0x21, 0xfd, 0x5a }) // ISlangUnknown - SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE; - SLANG_COM_BASE_IUNKNOWN_ADD_REF - SLANG_COM_BASE_IUNKNOWN_RELEASE - + SLANG_COM_BASE_IUNKNOWN_ALL + // ICastable + virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE; // ISlangSharedLibrary virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) SLANG_OVERRIDE; @@ -71,6 +70,9 @@ class DefaultSharedLibrary : public ISlangSharedLibrary, public ComBaseObject protected: + void* getInterface(const Guid& guid); + void* getObject(const Guid& guid); + SharedLibrary::Handle m_sharedLibraryHandle = nullptr; }; diff --git a/source/core/slang-string-util.cpp b/source/core/slang-string-util.cpp index c4b654072..a1f310401 100644 --- a/source/core/slang-string-util.cpp +++ b/source/core/slang-string-util.cpp @@ -319,7 +319,7 @@ UnownedStringSlice StringUtil::getAtInSplit(const UnownedStringSlice& in, char s ComPtr<ISlangBlob> StringUtil::createStringBlob(const String& string) { - return ComPtr<ISlangBlob>(new StringBlob(string)); + return StringBlob::create(string); } /* static */String StringUtil::calcCharReplaced(const UnownedStringSlice& slice, char fromChar, char toChar) diff --git a/source/core/slang-zip-file-system.cpp b/source/core/slang-zip-file-system.cpp index 1ed003d55..ce25066df 100644 --- a/source/core/slang-zip-file-system.cpp +++ b/source/core/slang-zip-file-system.cpp @@ -709,12 +709,12 @@ SlangResult ZipFileSystemImpl::storeArchive(bool blobOwnsContent, ISlangBlob** o if (blobOwnsContent) { // Takes a copy - blob = new RawBlob(m_data.getData(), Index(m_data.getSizeInBytes())); + blob = RawBlob::create(m_data.getData(), Index(m_data.getSizeInBytes())); } else { // Doesn't take a copy... Must use with care(!) - blob = new UnownedRawBlob(m_data.getData(), Index(m_data.getSizeInBytes())); + blob = UnownedRawBlob::create(m_data.getData(), Index(m_data.getSizeInBytes())); } *outBlob = blob.detach(); return SLANG_OK; diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index 361f92525..17785bdc6 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -55,6 +55,52 @@ namespace Slang { + // A temporary class that adapts `ISlangSharedLibrary_Dep1` to ISlangSharedLibrary + + class SharedLibraryDep1Adapter : public ComBaseObject, public ISlangSharedLibrary + { + public: + SLANG_COM_BASE_IUNKNOWN_ALL + + // ICastable + virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE; + + // ISlangSharedLibrary + virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) SLANG_OVERRIDE { return m_contained->findSymbolAddressByName(name); } + + SharedLibraryDep1Adapter(ISlangSharedLibrary_Dep1* dep1): + m_contained(dep1) + { + } + + protected: + void* getInterface(const Guid& guid) + { + if (guid == ISlangUnknown::getTypeGuid() || + guid == ICastable::getTypeGuid() || + guid == ISlangSharedLibrary::getTypeGuid()) + { + return static_cast<ISlangSharedLibrary*>(this); + } + return nullptr; + } + void* getObject(const Guid& guid) + { + SLANG_UNUSED(guid); + return nullptr; + } + + ComPtr<ISlangSharedLibrary_Dep1> m_contained; + }; + + void* SharedLibraryDep1Adapter::castAs(const SlangUUID& guid) + { + if (auto intf = getInterface(guid)) + { + return intf; + } + return getObject(guid); + } // !!!!!!!!!!!!!!!!!!!!!! free functions for DiagnosicSink !!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -81,7 +127,24 @@ namespace Slang { if (downstreamResult) { - return downstreamResult->getHostCallableSharedLibrary(outSharedLibrary); + // TODO(JS): Work around for not knowing actual interface this is returning, + // and needing to support deps interface + + ComPtr<ISlangSharedLibrary> lib; + SLANG_RETURN_ON_FAIL(downstreamResult->getHostCallableSharedLibrary(lib)); + + if (SLANG_SUCCEEDED(lib->queryInterface(ISlangSharedLibrary::getTypeGuid(), (void**)outSharedLibrary.writeRef()))) + { + return SLANG_OK; + } + + ComPtr<ISlangSharedLibrary_Dep1> libDep1; + if (SLANG_SUCCEEDED(lib->queryInterface(ISlangSharedLibrary_Dep1::getTypeGuid(), (void**)libDep1.writeRef()))) + { + // Okay, we need to adapt for now + outSharedLibrary = new SharedLibraryDep1Adapter(libDep1); + return SLANG_OK; + } } return SLANG_FAIL; } @@ -1304,8 +1367,9 @@ namespace Slang // Set up the library artifact ComPtr<IArtifact> artifact(new Artifact(ArtifactDesc::make(ArtifactKind::Library, Artifact::Payload::HostCPU), "slang-rt")); + ComPtr<IFileArtifactRepresentation> fileRep(new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::NameOnly, "slang-rt", nullptr, nullptr)); - artifact->addItem(fileRep); + artifact->addRepresentation(fileRep); options.libraries.add(artifact); } @@ -2122,10 +2186,10 @@ namespace Slang } // Need to turn into a blob - RefPtr<ListBlob> blob(new ListBlob); - // Swap the streams contents into the blob - stream.swapContents(blob->m_data); - m_containerBlob = blob; + List<uint8_t> blobData; + stream.swapContents(blobData); + + m_containerBlob = ListBlob::moveCreate(blobData); return res; } diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp index 636a32a4d..6667a6d9d 100644 --- a/source/slang/slang-ir-link.cpp +++ b/source/slang/slang-ir-link.cpp @@ -1411,8 +1411,7 @@ LinkedIR linkIR( }); for (IArtifact* artifact : linkage->m_libModules) { - ModuleLibrary* library = (ModuleLibrary*)artifact->findItemObject(ModuleLibrary::getTypeGuid()); - if (library) + if (auto library = findRepresentation<ModuleLibrary>(artifact)) { irModules.addRange(library->m_modules.getBuffer()->readRef(), library->m_modules.getCount()); } diff --git a/source/slang/slang-module-library.cpp b/source/slang/slang-module-library.cpp index b60555766..75450d7b3 100644 --- a/source/slang/slang-module-library.cpp +++ b/source/slang/slang-module-library.cpp @@ -91,7 +91,7 @@ SlangResult loadModuleLibrary(const Byte* inBytes, size_t bytesCount, EndToEndCo SlangResult loadModuleLibrary(ArtifactKeep keep, IArtifact* artifact, EndToEndCompileRequest* req, RefPtr<ModuleLibrary>& outLibrary) { - if (auto foundLibrary = (ModuleLibrary*)artifact->findItemObject(ModuleLibrary::getTypeGuid())) + if (auto foundLibrary = findRepresentation<ModuleLibrary>(artifact)) { outLibrary = foundLibrary; return SLANG_OK; @@ -107,7 +107,7 @@ SlangResult loadModuleLibrary(ArtifactKeep keep, IArtifact* artifact, EndToEndCo if (canKeep(keep)) { - artifact->addItem(library); + artifact->addRepresentation(library); } outLibrary = library; diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index 5b14ca24f..6351ffbd4 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -1506,7 +1506,7 @@ struct OptionsParser return SLANG_FAIL; } } - artifact->addItem(fileRep); + artifact->addRepresentation(fileRep); SLANG_RETURN_ON_FAIL(_addLibraryReference(requestImpl, artifact)); } diff --git a/source/slang/slang-repro.cpp b/source/slang/slang-repro.cpp index ad275ee7b..ad1bc25fc 100644 --- a/source/slang/slang-repro.cpp +++ b/source/slang/slang-repro.cpp @@ -249,15 +249,15 @@ struct StoreContext base[fileState]->contents = offsetContents; } - if (srcPathInfo->m_canonicalPath && base[fileState]->canonicalPath.isNull()) + if (srcPathInfo->m_canonicalPath.getLength() && base[fileState]->canonicalPath.isNull()) { - auto offsetCanonicalPath = fromString(srcPathInfo->m_canonicalPath->getString()); + auto offsetCanonicalPath = fromString(srcPathInfo->m_canonicalPath); base[fileState]->canonicalPath = offsetCanonicalPath; } - if (srcPathInfo->m_uniqueIdentity && base[fileState]->uniqueIdentity.isNull()) + if (srcPathInfo->m_uniqueIdentity.getLength() && base[fileState]->uniqueIdentity.isNull()) { - auto offsetUniqueIdentity = fromString(srcPathInfo->m_uniqueIdentity->getString()); + auto offsetUniqueIdentity = fromString(srcPathInfo->m_uniqueIdentity); base[fileState]->uniqueIdentity = offsetUniqueIdentity; } } @@ -668,20 +668,19 @@ struct LoadContext // If wasn't loaded, and has contents, use that if (!blob && file->contents) { - blob = new StringBlob(m_base->asRaw(file->contents)->getSlice()); + blob = StringBlob::create(m_base->asRaw(file->contents)->getSlice()); } dstInfo = new CacheFileSystem::PathInfo(String()); if (file->uniqueIdentity) { - String uniqueIdentity = m_base->asRaw(file->uniqueIdentity)->getSlice(); - dstInfo->m_uniqueIdentity = new StringBlob(uniqueIdentity); + dstInfo->m_uniqueIdentity = m_base->asRaw(file->uniqueIdentity)->getSlice(); } if (file->canonicalPath) { - dstInfo->m_canonicalPath = new StringBlob(m_base->asRaw(file->canonicalPath)->getSlice()); + dstInfo->m_canonicalPath = m_base->asRaw(file->canonicalPath)->getSlice(); } if (blob) @@ -865,13 +864,13 @@ struct LoadContext for (const auto& pair : context.m_fileToPathInfoMap) { CacheFileSystem::PathInfo* pathInfo = pair.Value; - SLANG_ASSERT(pathInfo->m_uniqueIdentity); - dstUniqueMap.Add(pathInfo->m_uniqueIdentity->getString(), pathInfo); + SLANG_ASSERT(pathInfo->m_uniqueIdentity.getLength()); + dstUniqueMap.Add(pathInfo->m_uniqueIdentity, pathInfo); // Add canonical paths too.. - if (pathInfo->m_canonicalPath) + if (pathInfo->m_canonicalPath.getLength()) { - String canonicalPath = pathInfo->m_canonicalPath->getString(); + String canonicalPath = pathInfo->m_canonicalPath; dstPathMap.AddIfNotExists(canonicalPath, pathInfo); } @@ -1050,8 +1049,8 @@ struct LoadContext for (const auto& pair : context.m_fileToPathInfoMap) { CacheFileSystem::PathInfo* pathInfo = pair.Value; - SLANG_ASSERT(pathInfo->m_uniqueIdentity); - dstUniqueMap.Add(pathInfo->m_uniqueIdentity->getString(), pathInfo); + SLANG_ASSERT(pathInfo->m_uniqueIdentity.getLength()); + dstUniqueMap.Add(pathInfo->m_uniqueIdentity, pathInfo); } } diff --git a/source/slang/slang-workspace-version.cpp b/source/slang/slang-workspace-version.cpp index 2451290f5..ebfe9218a 100644 --- a/source/slang/slang-workspace-version.cpp +++ b/source/slang/slang-workspace-version.cpp @@ -330,8 +330,7 @@ SlangResult Workspace::loadFile(const char* path, ISlangBlob** outBlob) RefPtr<DocumentVersion> doc; if (openedDocuments.TryGetValue(canonnicalPath, doc)) { - RefPtr<StringBlob> stringBlob = new StringBlob(doc->getText()); - *outBlob = stringBlob.detach(); + *outBlob = StringBlob::create(doc->getText()).detach(); return SLANG_OK; } return Slang::OSFileSystem::getExtSingleton()->loadFile(path, outBlob); @@ -479,7 +478,8 @@ Module* WorkspaceVersion::getOrLoadModule(String path) if (!doc) return nullptr; ComPtr<ISlangBlob> diagnosticBlob; - RefPtr<StringBlob> sourceBlob = new StringBlob((*doc)->getText()); + auto sourceBlob = StringBlob::create((*doc)->getText()); + auto moduleName = getMangledNameFromNameString(path.getUnownedSlice()); linkage->contentAssistInfo.primaryModuleName = linkage->getNamePool()->getName(moduleName); linkage->contentAssistInfo.primaryModulePath = path; @@ -494,7 +494,7 @@ Module* WorkspaceVersion::getOrLoadModule(String path) auto parsedModule = linkage->loadModuleFromSource( moduleName.getBuffer(), path.getBuffer(), - sourceBlob.Ptr(), + sourceBlob, diagnosticBlob.writeRef()); if (parsedModule) { diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index f74a4a5d6..684b0660d 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -4515,8 +4515,7 @@ SlangResult EndToEndCompileRequest::addLibraryReference(const void* libData, siz // Create an artifact without any name (as one is not provided) ComPtr<IArtifact> artifact(new Artifact(desc, String())); - - artifact->addItem(library); + artifact->addRepresentation(library); return _addLibraryReference(this, artifact); } @@ -4929,12 +4928,12 @@ SlangResult EndToEndCompileRequest::saveRepro(ISlangBlob** outBlob) SLANG_RETURN_ON_FAIL(ReproUtil::saveState(this, &stream)); - RefPtr<ListBlob> listBlob(new ListBlob); - // Put the content of the stream in the blob - stream.swapContents(listBlob->m_data); - *outBlob = listBlob.detach(); + List<uint8_t> data; + stream.swapContents(data); + + *outBlob = ListBlob::moveCreate(data).detach(); return SLANG_OK; } diff --git a/tools/gfx/cuda/cuda-device.cpp b/tools/gfx/cuda/cuda-device.cpp index 1a4a142d0..be5dbbc96 100644 --- a/tools/gfx/cuda/cuda-device.cpp +++ b/tools/gfx/cuda/cuda-device.cpp @@ -1061,7 +1061,8 @@ SLANG_NO_THROW SlangResult SLANG_MCALL DeviceImpl::readTextureResource( size_t* outPixelSize) { auto textureImpl = static_cast<TextureResourceImpl*>(texture); - RefPtr<ListBlob> blob = new ListBlob(); + + List<uint8_t> blobData; auto desc = textureImpl->getDesc(); auto width = desc->size.width; @@ -1071,7 +1072,7 @@ SLANG_NO_THROW SlangResult SLANG_MCALL DeviceImpl::readTextureResource( size_t pixelSize = sizeInfo.blockSizeInBytes / sizeInfo.pixelsPerBlock; size_t rowPitch = width * pixelSize; size_t size = height * rowPitch; - blob->m_data.setCount((Index)size); + blobData.setCount((Index)size); CUDA_MEMCPY2D copyParam; memset(©Param, 0, sizeof(copyParam)); @@ -1080,7 +1081,7 @@ SLANG_NO_THROW SlangResult SLANG_MCALL DeviceImpl::readTextureResource( copyParam.srcArray = textureImpl->m_cudaArray; copyParam.dstMemoryType = CU_MEMORYTYPE_HOST; - copyParam.dstHost = blob->m_data.getBuffer(); + copyParam.dstHost = blobData.getBuffer(); copyParam.dstPitch = rowPitch; copyParam.WidthInBytes = copyParam.dstPitch; copyParam.Height = height; @@ -1088,6 +1089,9 @@ SLANG_NO_THROW SlangResult SLANG_MCALL DeviceImpl::readTextureResource( *outRowPitch = rowPitch; *outPixelSize = pixelSize; + + auto blob = ListBlob::moveCreate(blobData); + returnComPtr(outBlob, blob); return SLANG_OK; } @@ -1099,13 +1103,18 @@ SLANG_NO_THROW Result SLANG_MCALL DeviceImpl::readBufferResource( ISlangBlob** outBlob) { auto bufferImpl = static_cast<BufferResourceImpl*>(buffer); - RefPtr<ListBlob> blob = new ListBlob(); - blob->m_data.setCount((Index)size); + + List<uint8_t> blobData; + + blobData.setCount((Index)size); cudaMemcpy( - blob->m_data.getBuffer(), + blobData.getBuffer(), (uint8_t*)bufferImpl->m_cudaMemory + offset, size, cudaMemcpyDefault); + + auto blob = ListBlob::moveCreate(blobData); + returnComPtr(outBlob, blob); return SLANG_OK; } diff --git a/tools/gfx/d3d11/d3d11-device.cpp b/tools/gfx/d3d11/d3d11-device.cpp index 1b2f6ec1d..aa665ebd4 100644 --- a/tools/gfx/d3d11/d3d11-device.cpp +++ b/tools/gfx/d3d11/d3d11-device.cpp @@ -371,9 +371,11 @@ SlangResult DeviceImpl::readTextureResource( { D3D11_MAPPED_SUBRESOURCE mappedResource; SLANG_RETURN_ON_FAIL(m_immediateContext->Map(stagingTexture, 0, D3D11_MAP_READ, 0, &mappedResource)); - RefPtr<ListBlob> blob = new ListBlob(); - blob->m_data.setCount(bufferSize); - char* buffer = (char*)blob->m_data.begin(); + + List<uint8_t> data; + + data.setCount(bufferSize); + char* buffer = (char*)data.begin(); for (size_t y = 0; y < textureDesc.Height; y++) { memcpy( @@ -383,6 +385,9 @@ SlangResult DeviceImpl::readTextureResource( } // Make sure to unmap m_immediateContext->Unmap(stagingTexture, 0); + + ComPtr<ISlangBlob> blob = ListBlob::moveCreate(data); + returnComPtr(outBlob, blob); return SLANG_OK; } diff --git a/tools/gfx/d3d12/d3d12-device.cpp b/tools/gfx/d3d12/d3d12-device.cpp index 3578729d9..f5c457809 100644 --- a/tools/gfx/d3d12/d3d12-device.cpp +++ b/tools/gfx/d3d12/d3d12-device.cpp @@ -231,10 +231,14 @@ Result DeviceImpl::captureTextureToSurface( SLANG_RETURN_ON_FAIL(dxResource->Map(0, &readRange, reinterpret_cast<void**>(&data))); - RefPtr<Slang::ListBlob> resultBlob = new Slang::ListBlob(); - resultBlob->m_data.setCount(bufferSize); - memcpy(resultBlob->m_data.getBuffer(), data, bufferSize); + List<uint8_t> blobData; + + blobData.setCount(bufferSize); + memcpy(blobData.getBuffer(), data, bufferSize); dxResource->Unmap(0, nullptr); + + auto resultBlob = Slang::ListBlob::moveCreate(blobData); + returnComPtr(outBlob, resultBlob); return SLANG_OK; } @@ -1748,7 +1752,7 @@ Result DeviceImpl::readBufferResource( buffer->getDesc()->memoryType != MemoryType::ReadBack ? stageBuf : resource; // Map and copy - RefPtr<ListBlob> blob = new ListBlob(); + List<uint8_t> blobData; { UINT8* data; D3D12_RANGE readRange = { 0, size }; @@ -1757,11 +1761,12 @@ Result DeviceImpl::readBufferResource( stageBufRef.getResource()->Map(0, &readRange, reinterpret_cast<void**>(&data))); // Copy to memory buffer - blob->m_data.setCount(size); - ::memcpy(blob->m_data.getBuffer(), data, size); + blobData.setCount(size); + ::memcpy(blobData.getBuffer(), data, size); stageBufRef.getResource()->Unmap(0, nullptr); } + auto blob = ListBlob::moveCreate(blobData); returnComPtr(outBlob, blob); return SLANG_OK; } @@ -1782,8 +1787,9 @@ Result DeviceImpl::createProgram( { if (outDiagnosticBlob && d3dDiagnosticBlob) { - RefPtr<StringBlob> diagnosticBlob = - new StringBlob(String((const char*)d3dDiagnosticBlob->GetBufferPointer())); + String diagnostic((const char*)d3dDiagnosticBlob->GetBufferPointer()); + auto diagnosticBlob = StringBlob::create(diagnostic); + returnComPtr(outDiagnosticBlob, diagnosticBlob); } return rootShaderLayoutResult; diff --git a/tools/gfx/immediate-renderer-base.cpp b/tools/gfx/immediate-renderer-base.cpp index c598a3a67..611741c46 100644 --- a/tools/gfx/immediate-renderer-base.cpp +++ b/tools/gfx/immediate-renderer-base.cpp @@ -711,13 +711,17 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ImmediateRendererBase::readBufferResource size_t size, ISlangBlob** outBlob) { - RefPtr<ListBlob> blob = new ListBlob(); - blob->m_data.setCount((Index)size); + List<uint8_t> blobData; + + blobData.setCount((Index)size); auto content = (uint8_t*)map(buffer, gfx::MapFlavor::HostRead); if (!content) return SLANG_FAIL; - memcpy(blob->m_data.getBuffer(), content + offset, size); + memcpy(blobData.getBuffer(), content + offset, size); unmap(buffer, offset, size); + + auto blob = ListBlob::moveCreate(blobData); + returnComPtr(outBlob, blob); return SLANG_OK; } diff --git a/tools/gfx/open-gl/render-gl.cpp b/tools/gfx/open-gl/render-gl.cpp index 0cf05e665..7daf577ef 100644 --- a/tools/gfx/open-gl/render-gl.cpp +++ b/tools/gfx/open-gl/render-gl.cpp @@ -2246,9 +2246,10 @@ SLANG_NO_THROW Result SLANG_MCALL GLDevice::readTextureResource( if (outPixelSize) *outPixelSize = sizeof(uint32_t); - RefPtr<ListBlob> blob = new ListBlob(); - blob->m_data.setCount(requiredSize); - auto buffer = blob->m_data.begin(); + List<uint8_t> blobData; + + blobData.setCount(requiredSize); + auto buffer = blobData.begin(); glBindTexture(resource->m_target, resource->m_handle); glGetTexImage(resource->m_target, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); @@ -2263,8 +2264,8 @@ SLANG_NO_THROW Result SLANG_MCALL GLDevice::readTextureResource( } } + auto blob = ListBlob::moveCreate(blobData); returnComPtr(outBlob, blob); - return SLANG_OK; } diff --git a/tools/gfx/vulkan/vk-device.cpp b/tools/gfx/vulkan/vk-device.cpp index d62734394..c2d82f8a7 100644 --- a/tools/gfx/vulkan/vk-device.cpp +++ b/tools/gfx/vulkan/vk-device.cpp @@ -797,8 +797,9 @@ SlangResult DeviceImpl::readTextureResource( Size* outPixelSize) { auto textureImpl = static_cast<TextureResourceImpl*>(texture); - RefPtr<ListBlob> blob = new ListBlob(); + List<uint8_t> blobData; + auto desc = textureImpl->getDesc(); auto width = desc->size.width; auto height = desc->size.height; @@ -828,8 +829,8 @@ SlangResult DeviceImpl::readTextureResource( } // Calculate the total size taking into account the array bufferSize *= arraySize; - // TODO: Change Index to Count? - blob->m_data.setCount(Index(bufferSize)); + + blobData.setCount(Count(bufferSize)); VKBufferHandleRAII staging; SLANG_RETURN_ON_FAIL(staging.init( @@ -880,11 +881,14 @@ SlangResult DeviceImpl::readTextureResource( SLANG_RETURN_ON_FAIL( m_api.vkMapMemory(m_device, staging.m_memory, 0, bufferSize, 0, &mappedData)); - ::memcpy(blob->m_data.getBuffer(), mappedData, bufferSize); + ::memcpy(blobData.getBuffer(), mappedData, bufferSize); m_api.vkUnmapMemory(m_device, staging.m_memory); *outPixelSize = pixelSize; *outRowPitch = rowPitch; + + auto blob = ListBlob::moveCreate(blobData); + returnComPtr(outBlob, blob); return SLANG_OK; } @@ -894,8 +898,9 @@ SlangResult DeviceImpl::readBufferResource( { BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(inBuffer); - RefPtr<ListBlob> blob = new ListBlob(); - blob->m_data.setCount(size); + List<uint8_t> blobData; + + blobData.setCount(size); // create staging buffer VKBufferHandleRAII staging; @@ -920,9 +925,11 @@ SlangResult DeviceImpl::readBufferResource( void* mappedData = nullptr; SLANG_RETURN_ON_FAIL(m_api.vkMapMemory(m_device, staging.m_memory, 0, size, 0, &mappedData)); - ::memcpy(blob->m_data.getBuffer(), mappedData, size); + ::memcpy(blobData.getBuffer(), mappedData, size); m_api.vkUnmapMemory(m_device, staging.m_memory); + auto blob = ListBlob::moveCreate(blobData); + returnComPtr(outBlob, blob); return SLANG_OK; } |
