I'm at the point now where I'm ready to dive into shaders, though I've been using a module based system as my means for learning how to do graphics programming (which I've written).
Since I'm working with D3D, I'd like to just make a shaders directory in my project root, store shaders there, and access them quickly.
There are obviously multiple ways to do this, but I don't have a very clear idea of obtaining my project's root directory. Is there a predefined macro for this - or a function of some sort for accessing a project's root folder?
Most languages have a method to get the application path, but most will wrap the GetModuleFileName() function, passing a null module handle.
You can then strip the executable name from the resulting path to get the base folder.
See this question for an extensive list of methods.
DWORD WINAPI [GetCurrentDirectory][1](
__in DWORD nBufferLength,
__out LPTSTR lpBuffer
);
Retrieves the current directory for the current process.
I believe this is the function you are looking for. You then append the subdirectory path that the shaders are located in respect to the full path returned that is where your program was executed from.
Related
The current documentation of both functions reads very similar to each another:
System.IOUtils.TPath.IsUNCRooted
System.IOUtils.TPath.IsUNCPath
Both are static members of the same class, with one of them decorated inline, so I wouldn't think they are separate implementations with equivalent functionality you often find across various Delphi classes (although examples within a common class do exist in Embarcadero's standard library).
Specifically, I can't come up with a case where a path is a valid UNC path but not a rooted UNC path. So what does IsUNCRooted even mean?
IsUNCRooted only checks if the parameter starts with an UNC sequence, while IsUNCPath also checks the rest for valid path names. So a valid UNCPath is indeed also UNC rooted, but not always the other way round.
I'm using NVRTC to compile a kernel. The relevant API call is:
nvrtcResult nvrtcCreateProgram (
nvrtcProgram* prog,
const char* src,
const char* name,
int numHeaders,
const char** headers,
const char** includeNames )
As you can see, the source is a raw string, and not associated with a file. That means that when you --generate-line-info, you get line numbers, but no related filename. And that means that if you then use, say, NSight Compute - you won't be able to see your kernel source code.
Obviously, neither NSight Compute itself, nor NVRTC itself, can figure out that the raw source is mirrored in some file. But there has to be some way to get around this:
Perhaps I'm missing something in the NVRTC API which can make the source <-> file association?
Perhaps we can manipulate the resulting compiled program (reasonably, not manually, or write-my-own-new-API) to make the association?
Perhaps we can shove the source code into the compiled program somehow?
Here's my initial workaround:
Place your source in a file, say my_kernel.cuh.
Create the string:
#include "my_kernel.cuh"
Compile just this string using NVRTC
Now, NVRTC is able to associate included files' sources with the files, so it's only a stub that will be missing in terms of source<->file association.
Caveat: You will need to be careful about paths - NVRTC's include paths, the working directory from which you invoke your program vs the directory of the source file etc.
It seems NVRTC does provides a default filename, such that if you place your source in the file with that name - NSight Compute may be able to find it.
The name is the one you passed to nvrtcCreateProgram() as the name argument.
So, if your kernel function (i.e. your __global__ function) is in my_kernel.cuh, and you place this file in the working directory of the profile program (which you tell NSight Compute about), or in one of the include directories you built your program with, you'll be able to read your source. If the original file's own directory is also one of the include directories, then you're in luck and you don't even have to make a copy.
In the Linux Kernel: I have a file (ie, a 'struct file') of a directory. Let's call it f_child. I need a file reference for the parent directory.
I'm currently retrieving this like so:
1) Create a 'struct path' from the f_dentry->d_parent and f_vfsmnt of f_child. I check, of course, that the d_parent is non-null.
2) Get the path (ie, a string, not a struct path... a char *) of the parent of f_child using d_path, passing in the path we retrieved from step 1.
3) Pass that string to filp_open, which returns the struct file * that I want.
It seems to work. I'm worried though about the assumption I'm making at step 1 that the vfs mount of the parent and child will be the same. Will that bite me at some point? Is there a better way of doing this? Clearly, I don't understand the vfs mount structure well enough. Do all dentries belonging to the same super block have the same vfs mount?
btw: I anticipate, and a appreciate, the rebuke for opening a file in the Kernel, but what I'm doing really does require it. :)
Thanks!
I stumbled upon this very helpful page:
http://kedar.dumpstack.com/pubs/al_vfsmounts.html
(Also posted here in case that goes away):
http://kerneltrap.org/node/3749
While short, this is valuable for anyone trying to begin to understand the workings of the vfs because it goes beyond describing the parts (superblock, inode, dentry, etc.) to describing how they work together to create the namespace users interact with.
Anyway, if I'm reading this correctly, a tree of dentries are rooted from a super block corresponding to a file system, not a vfsmount. So I have to check to make sure that the d_parent and the dentry have the same vfs mount. The mnt_root check I mention below accomplishes this.
So, it's not null I need to check at step 1 but these two things (I get this from the implementation of __d_path in fs/dcache.c):
mnt_root. If the f_dentry of f_child is the same as mnt_root of its f_vfsmnt, then I can't look at f_dentry->d_parent. We're at the root of the mount. If I want to go above that dentry, I have to move up the tree by looking at the dentry f_vfsmnt->mnt_mountpoint and the vfsmount f_vfsmnt->mnt_parent.
IS_ROOT. IS_ROOT takes a dentry, and if it returns true, then there is no point looking above that. We're at the root of the file system, which may not be the root of our namespace.
Now that I understand some more, I realize that the post by J-16 SDiZ is helpful:
Linux Kernel dentry and inode
He references the tomoyo implementation of getting a real path:
http://lxr.linux.no/linux+v2.6.37/security/tomoyo/realpath.c#L86
I've been looking recently into creating a new native language. I understand the (very) basics of the PE format and I've grabbed an assembler with a fairly kind interface off the webs, which I've successfully used to implement some simple functions. But I've run into a problem using functions from a library. The only way that I've called library functions from a dynamically compiled function previously is to pass in the function pointer manually- something I can't do if I create PE files and execute them in their own process. Now, I'm not planning on using the CRT, but I will need access to the Win API to implement my own standard libraries. How do I generate a reference to a WinAPI function so that the PE loader will patch it up?
You need to write an import table. It's basically a list of function names that you wish to use in your application. It's pointed to by the PE header. The loader loads the DLL files into the process memory space for you, finds the requested function in their export table and leaves the address for it in the import table. You then usually dereference that and jmp there.
Check out Izelion's assembly tutorial for the full details and for asm examples.
How about starting by emitting C instead of assembly? Then writing directly to ASM is just an optimization.
I'm not being facetious: most compilers turn out some kind of intermediate code before the final native code pass.
I realize you're trying to get away from all the null-delmited rigmarole, but you'll need that for the WinAPI functions anyway.
Re-reading your question: you do realize that you can get the WinAPI function addresses by calling LoadLibrary(), then calling GetProcAddress(), and then setting up the call...right?
If you want to see how to bootstrap this from pure assembly: the old SDKs had ASM sample code, probably the new ones still do. If they don't, the DDK will.
The HINSTANCE of a win32 application is passed to WinMain, but is there any other way of determining the current HINSTANCE (in case you couldn't tell, I'm very new to win32 programming!)? I need to create a window inside of a library and (since the library is cross platform), id prefer not to have to pass it in.
If memory serves, GetModuleHandle(NULL); returns the instance handle.
__ImageBase is your friend, especially in the case of libraries.
Note that the linked blog post (by R. Chen, although not the same post as the one linked by Brian Bondy) is worth reading (including the comments!)
If you are using MFC, you can use AfxGetInstanceHandle.
If you are not using MFC you can use: GetWindowLong(hWnd, GWL_HINSTANCE)
The function AfxGetStaticModuleState() does the trick.
If you call it within a dll, the functions returns the handle to the dll, if the call within a exe it returns the handle to the executable.
DWORD size;
TCHAR fileName [MAX_PATH];
HMODULE hModule = AfxGetStaticModuleState()->m_hCurrentInstanceHandle;
::GetModuleFileName (hModule, fileName, size);