-
Notifications
You must be signed in to change notification settings - Fork 792
Create new class to handle external validation, and rename existing dll loading class. #7514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Create new class to handle external validation, and rename existing dll loading class. #7514
Conversation
733ce1e
to
c527502
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a number of comments, but many of these issues would have been noticed when trying to create a unit test that used this new DxcDllExtValidationSupport
class. I think we need a unit test.
f65abd9
to
09be489
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are all the changes to SPIRV-Tools here intended?
792ca55
to
cba829b
Compare
An accidental git add . put these changes in :( |
include/dxc/Support/dxcapi.use.h
Outdated
@@ -31,7 +31,7 @@ class DllLoader { | |||
|
|||
public: | |||
DllLoader() = default; | |||
DllLoader(const DllLoader &) = delete; | |||
DllLoader(const DllLoader &) = default; // needed for HlslIntellisenseSupport |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please mark this as deleted and remove the HlslIntellisenseSupport move constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to delete this solely because it's an interface class? Or is there some other reason?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no way for someone who has a pointer to a DllLoader
instance to safely copy or move it, so we shouldn't have copy/move constructors for it. Plus, since there's no actual need to ever copy these we shouldn't be spending time trying to make it work. As it is now, the default copy constructor for SpecificDllLoader
will end up leaking the dll HANDLE, so we don't want people trying to copy that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for bearing with me. I think the interface now is in much better shape. I look forward to seeing this hooked up to some real functionality so we can understand how it all fits together!
include/dxc/Support/HLSLOptions.h
Outdated
/// Sets up the specified DllLoader instance as per the given options. | ||
int SetupDllLoader(const DxcOpts &opts, dxc::SpecificDllLoader &dxcSupport, | ||
llvm::raw_ostream &errors); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment doesn't match the function here - is the argument a DllLoader
or a SpecificDllLoader
? Also you've forward declared both of these above, but only one is used.
include/dxc/Support/dxcapi.extval.h
Outdated
HRESULT CreateInstance2Impl(IMalloc *pMalloc, REFCLSID clsid, REFIID riid, | ||
IUnknown **pResult) override; | ||
|
||
HRESULT Initialize() { return InitializeInternal("DxcCreateInstance"); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does InitializeInternal
take a fnName
argument if it's only ever called with a fixed string? Do we need InitializeInternal
at all, or should we just update the implementation to be an implementation of Initialize()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, looks like we dont need it at all. I'll remove InitializeInternal and move its implementation to Initialize().
include/dxc/Support/dxcapi.use.h
Outdated
// Also bring visibility into the interface definition of this function | ||
// which takes 2 args | ||
using DllLoader::CreateInstanceImpl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These using
statements are no longer necessary
class DllLoader; | ||
class SpecificDllLoader; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need both of these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, without them the uses in 364 / 369 fail to compile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'm missing something, but I only see uses of SpecificDllLoader
on those lines. Is DllLoader
also used?
include/dxc/Support/dxcapi.use.h
Outdated
HRESULT InitializeForDll(LPCSTR dll, LPCSTR entryPoint) { | ||
HRESULT OverrideDll(LPCSTR dll, LPCSTR entryPoint) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This came from a suggestion of mine, but now that the API has been simplified a bit and this only in SpecificDllLoader I find many of the updated users of this to be confusing. We often create the SpecificDllLoader, don't call Initialize() at all, and then call OverrideDll
- this isn't really overriding, it's just initializing. I think I steered you wrong and the original InitializeForDll
name was better.
include/dxc/Support/dxcapi.use.h
Outdated
@@ -85,7 +129,7 @@ class DxcDllSupport { | |||
other.m_createFn2 = nullptr; | |||
} | |||
|
|||
~DxcDllSupport() { Cleanup(); } | |||
~SpecificDllLoader() { Cleanup(); } | |||
|
|||
HRESULT Initialize() { | |||
return InitializeInternal(kDxCompilerLib, "DxcCreateInstance"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I'm saying is is "do we even want an Initialize()
function with no parameters on SpecificDllLoader? What if SpecificDllLoader
only had InitializeForDll()
and to use it you had to specify which dll you wanted to load?
For convenience, we could subclass this with DxcompilerDllLoader
that specifically loads dxcompiler.dll
, much like we do with HlslIntellisenseSupport
. That object could reasonably have a Initialize()
that knows what Dll to load. This would match the Initialize()
on the external validator class that knows which two Dlls it's going to load.
To your last comment, I do think there is an argument to be made for having an Initialize() with no arguments. |
Looks like some changes to SPIRV-Tools have snuck in again. |
This comment seems to have missed the second half of my suggestion:
So what I mean is that we could have something like: class DxCompilerDllLoader : public SpecificDllLoader {
public:
HRESULT Initialize() {
return InitializeForDll(kDxCompilerLib, "DxcCreateInstance");
}
}; For usages where we want to load DxcompilerDllLoader DXCSupport;
DXCSupport.Initialize();
// Call APIs that accept the DllLoader interface For a usage that wants some other specific Dll, you would use SpecificDllLoader DXRFallbackSupport;
DXRFallbackSupport.InitializeForDll("DxrFallbackCompiler.dll",
"DxcCreateDxrFallbackCompiler");
// Call APIs that accept the DllLoader interface The nice thing here is that for The point I'm trying to make here is that |
class DllLoader; | ||
class SpecificDllLoader; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'm missing something, but I only see uses of SpecificDllLoader
on those lines. Is DllLoader
also used?
VERIFY_SUCCEEDED(dllSupport.Initialize()); | ||
VERIFY_SUCCEEDED( | ||
dllSupport.InitializeForDll(dxc::kDxCompilerLib, "DxcCreateInstance")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change this from Initialize()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without taking into account the overarching comment you just made in this latest review, I had thought being extra explicit was nice, rather than using the default initializer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we have DxCompilerDllLoader
there's an argument that using that type in the API would be even more explicit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking pretty good. Just a few more notes and questions inline.
@@ -125,7 +125,7 @@ class DxcContext { | |||
|
|||
private: | |||
DxcOpts &m_Opts; | |||
DxcDllSupport &m_dxcSupport; | |||
SpecificDllLoader &m_dxcSupport; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will presumably need to become a DllLoader
in the future in order to support the ext validation case, right? This is using a SpecificDllLoader for now since you're planning to make those changes separately?
@@ -43,7 +46,7 @@ inline bool wcsieqopt(LPCWSTR text, LPCWSTR opt) { | |||
return (text[0] == L'-' || text[0] == L'/') && wcsieq(text + 1, opt); | |||
} | |||
|
|||
static dxc::DxcDllSupport g_DxcSupport; | |||
static dxc::SpecificDllLoader g_DxcSupport; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this one be a DxCompilerDllLoader
? That seems to be what its used for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because on line 323, it loads an arbitrary dll from the command line options. This would break the specificity of that class, so it seems to me SpecificDllLoader is as specific (the least abstract) as we can get.
if (!dxcSupport.IsEnabled()) { | ||
IFT(dxcSupport.Initialize()); | ||
IFT(dxcSupport.InitializeForDll(kDxCompilerLib, "DxcCreateInstance")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make more sense for EnsureEnabled
to take a DxCompilerDllLoader
? I think that everywhere that uses it pretty clearly intends to be loading dxcompiler.dll.
Do note though that this API will probably need to change once we start plugging the external validator into the various tools and tests, as it won't be able to handle that type as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. For example, dxc.cpp:1464 has a use of ensureenabled.
The dll that is loaded depends on dxcOpts, and the code dynamically loads a specified dll via the setup function on line 1455. Because that dll could potentially not be the standard dxcompiler.dll, I shouldn't change the type that ensure enabled takes. Writing the function body inline also seems ugly for a case by case basis.
I'll make sure the right changes are performed when combing over the dxc.cpp test suite specifically.
SpecificDllLoader m_dxcSupport; | ||
SpecificDllLoader m_dxrFallbackSupport; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be clearer if m_dxcSupport
were a DxCompilerDllLoader
here? m_dxrFallbackSupport
being a different SpecificDllLoader
makes sense though.
VERIFY_SUCCEEDED(dllSupport.Initialize()); | ||
VERIFY_SUCCEEDED( | ||
dllSupport.InitializeForDll(dxc::kDxCompilerLib, "DxcCreateInstance")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we have DxCompilerDllLoader
there's an argument that using that type in the API would be even more explicit.
This PR creates a class that is responsible for loading and unloading dxil.dll, allowing for external validation.
Tests are added to test this class's functionality. Additionally, an interface is defined that joins the existing singular dll loading helper class, and the new class that tracks two dlls. The classes were renamed to be more abstract, as well as all existing uses of the original singular dll loader class.
Fixes #7422