Build patched Windows ZLUDA and execute native NGX DLSS diagnostics
This commit is contained in:
1 parent
64472e5a61
commit
3c28a82e34
17 files changed
+1114
-13
No files matched your search
@@ -0,0 +1,135 @@
|
||||
#pragma once
|
||||
#include "cuda_api.h"
|
||||
|
||||
namespace d4r::cuda {
|
||||
// Public CUDA Driver API layouts, kept independent of NVIDIA SDK headers.
|
||||
using Array = void*;
|
||||
using Texture = uint64_t;
|
||||
struct ArrayDescriptor { size_t width, height; uint32_t format, channels; };
|
||||
struct Array3DDescriptor {
|
||||
size_t width, height, depth;
|
||||
uint32_t format, channels, flags;
|
||||
};
|
||||
struct Copy2D {
|
||||
size_t srcX, srcY;
|
||||
uint32_t srcType, srcAlignment;
|
||||
const void* srcHost;
|
||||
CUdeviceptr srcDevice;
|
||||
Array srcArray;
|
||||
size_t srcPitch, dstX, dstY;
|
||||
uint32_t dstType, dstAlignment;
|
||||
void* dstHost;
|
||||
CUdeviceptr dstDevice;
|
||||
Array dstArray;
|
||||
size_t dstPitch, widthBytes, height;
|
||||
};
|
||||
struct ResourceDescriptor {
|
||||
uint32_t type, alignment;
|
||||
union { Array array; int reserved[32]; } resource;
|
||||
uint32_t flags, reserved;
|
||||
};
|
||||
struct TextureDescriptor {
|
||||
uint32_t addressMode[3], filterMode, flags, maxAnisotropy, mipmapFilterMode;
|
||||
float mipmapBias, minMipmapClamp, maxMipmapClamp, borderColor[4];
|
||||
int reserved[12];
|
||||
};
|
||||
static_assert(sizeof(Array3DDescriptor) == 40);
|
||||
static_assert(sizeof(ArrayDescriptor) == 24);
|
||||
static_assert(sizeof(Copy2D) == 128);
|
||||
static_assert(sizeof(ResourceDescriptor) == 144);
|
||||
static_assert(sizeof(TextureDescriptor) == 104);
|
||||
|
||||
struct ImageApi {
|
||||
CudaApi& cuda;
|
||||
#define D4R_IMAGE(name, ...) using name##_fn = int(WINAPI*)(__VA_ARGS__); name##_fn name = cuda.library.symbol<name##_fn>(#name)
|
||||
D4R_IMAGE(cuArray3DCreate_v2, Array*, const Array3DDescriptor*);
|
||||
D4R_IMAGE(cuArrayGetDescriptor_v2, ArrayDescriptor*, Array);
|
||||
D4R_IMAGE(cuArray3DGetDescriptor_v2, Array3DDescriptor*, Array);
|
||||
D4R_IMAGE(cuArrayDestroy, Array);
|
||||
D4R_IMAGE(cuMemcpy2D_v2, const Copy2D*);
|
||||
D4R_IMAGE(cuTexObjectCreate, Texture*, const ResourceDescriptor*, const TextureDescriptor*, const void*);
|
||||
D4R_IMAGE(cuTexObjectDestroy, Texture);
|
||||
D4R_IMAGE(cuTexObjectGetResourceDesc, ResourceDescriptor*, Texture);
|
||||
D4R_IMAGE(cuSurfObjectCreate, Texture*, const ResourceDescriptor*);
|
||||
D4R_IMAGE(cuSurfObjectDestroy, Texture);
|
||||
D4R_IMAGE(cuSurfObjectGetResourceDesc, ResourceDescriptor*, Texture);
|
||||
#undef D4R_IMAGE
|
||||
explicit ImageApi(CudaApi& api) : cuda(api) {}
|
||||
};
|
||||
|
||||
class Image {
|
||||
ImageApi& api_;
|
||||
void release() noexcept {
|
||||
if (object) {
|
||||
const int result = surface_ ? api_.cuSurfObjectDestroy(object) : api_.cuTexObjectDestroy(object);
|
||||
if (result) std::fprintf(stderr, "IMAGE_DESTROY object result=%d\n", result);
|
||||
object = 0;
|
||||
}
|
||||
if (array_) {
|
||||
const int result = api_.cuArrayDestroy(array_);
|
||||
if (result) std::fprintf(stderr, "IMAGE_DESTROY array result=%d\n", result);
|
||||
array_ = nullptr;
|
||||
}
|
||||
}
|
||||
Array array_ = nullptr;
|
||||
bool surface_;
|
||||
size_t rowBytes_, height_;
|
||||
public:
|
||||
Texture object = 0;
|
||||
Image(ImageApi& api, unsigned width, unsigned height, uint32_t format,
|
||||
unsigned channels, bool surface, unsigned filter = 0)
|
||||
: api_(api), surface_(surface), rowBytes_(size_t(width) * channels * (format == 16 ? 2 : 4)), height_(height) {
|
||||
try {
|
||||
const Array3DDescriptor descriptor{width, height, 0, format, channels, surface ? 2u : 0u};
|
||||
api_.cuda.check(api_.cuArray3DCreate_v2(&array_, &descriptor), "cuArray3DCreate_v2");
|
||||
ResourceDescriptor resource{};
|
||||
resource.resource.array = array_;
|
||||
if (surface) api_.cuda.check(api_.cuSurfObjectCreate(&object, &resource), "cuSurfObjectCreate");
|
||||
else {
|
||||
TextureDescriptor texture{};
|
||||
texture.addressMode[0] = texture.addressMode[1] = 1; // clamp
|
||||
texture.filterMode = filter;
|
||||
texture.flags = 2; // normalized coordinates
|
||||
api_.cuda.check(api_.cuTexObjectCreate(&object, &resource, &texture, nullptr), "cuTexObjectCreate");
|
||||
}
|
||||
ResourceDescriptor roundtrip{};
|
||||
api_.cuda.check(surface ? api_.cuSurfObjectGetResourceDesc(&roundtrip, object) :
|
||||
api_.cuTexObjectGetResourceDesc(&roundtrip, object), "CUDA object resource descriptor roundtrip");
|
||||
if (roundtrip.type != 0 || roundtrip.resource.array != array_ || roundtrip.flags != 0)
|
||||
throw std::runtime_error("CUDA object descriptor does not match its array");
|
||||
ArrayDescriptor twoD{};
|
||||
Array3DDescriptor threeD{};
|
||||
api_.cuda.check(api_.cuArrayGetDescriptor_v2(&twoD, array_), "cuArrayGetDescriptor_v2");
|
||||
api_.cuda.check(api_.cuArray3DGetDescriptor_v2(&threeD, array_), "cuArray3DGetDescriptor_v2");
|
||||
if (twoD.width != width || twoD.height != height || twoD.format != format || twoD.channels != channels ||
|
||||
threeD.width != width || threeD.height != height || threeD.depth != 0 || threeD.format != format ||
|
||||
threeD.channels != channels || threeD.flags != descriptor.flags)
|
||||
throw std::runtime_error("CUDA array descriptor geometry or format mismatch");
|
||||
} catch (...) { release(); throw; }
|
||||
}
|
||||
Image(const Image&) = delete;
|
||||
Image& operator=(const Image&) = delete;
|
||||
~Image() { release(); }
|
||||
void verify_wrong_object_kind() {
|
||||
ResourceDescriptor wrong{};
|
||||
const int result = surface_ ? api_.cuTexObjectGetResourceDesc(&wrong, object) :
|
||||
api_.cuSurfObjectGetResourceDesc(&wrong, object);
|
||||
if (!result) throw std::runtime_error("Wrong CUDA object kind was accepted as a valid resource");
|
||||
std::printf("CUDA wrong-kind descriptor safely rejected result=%d\n", result);
|
||||
}
|
||||
void upload(const void* source) {
|
||||
Copy2D copy{};
|
||||
copy.srcType = 1; copy.srcHost = source; copy.srcPitch = rowBytes_;
|
||||
copy.dstType = 3; copy.dstArray = array_;
|
||||
copy.widthBytes = rowBytes_; copy.height = height_;
|
||||
api_.cuda.check(api_.cuMemcpy2D_v2(©), "cuMemcpy2D_v2(host to diagnostic array)");
|
||||
}
|
||||
void download(void* destination) {
|
||||
Copy2D copy{};
|
||||
copy.srcType = 3; copy.srcArray = array_;
|
||||
copy.dstType = 1; copy.dstHost = destination; copy.dstPitch = rowBytes_;
|
||||
copy.widthBytes = rowBytes_; copy.height = height_;
|
||||
api_.cuda.check(api_.cuMemcpy2D_v2(©), "cuMemcpy2D_v2(diagnostic array to host)");
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user