Skip to content

Commit 9888709

Browse files
committed
Fix issue with newer 545.29.02 drivers
1 parent 41e26cd commit 9888709

File tree

3 files changed

+65
-17
lines changed

3 files changed

+65
-17
lines changed

nvidia-include/nvidia-drm-ioctl.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@
5656
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GET_DEV_INFO), \
5757
struct drm_nvidia_get_dev_info_params)
5858

59+
#define DRM_IOCTL_NVIDIA_GET_DEV_INFO_545 \
60+
DRM_IOWR((DRM_COMMAND_BASE + DRM_NVIDIA_GET_DEV_INFO), \
61+
struct drm_nvidia_get_dev_info_params_545)
62+
5963
/*
6064
* XXX Solaris compiler has issues with DRM_IO. None of this is supported on
6165
* Solaris anyway, so just skip it.
@@ -136,6 +140,22 @@ struct drm_nvidia_get_dev_info_params {
136140
uint32_t sector_layout; /* OUT */
137141
};
138142

143+
struct drm_nvidia_get_dev_info_params_545 {
144+
uint32_t gpu_id; /* OUT */
145+
uint32_t primary_index; /* OUT; the "card%d" value */
146+
147+
uint32_t supports_alloc; /* OUT */
148+
/* The generic_page_kind, page_kind_generation, and sector_layout
149+
* fields are only valid if supports_alloc is true.
150+
* See DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D definitions of these. */
151+
uint32_t generic_page_kind; /* OUT */
152+
uint32_t page_kind_generation; /* OUT */
153+
uint32_t sector_layout; /* OUT */
154+
uint32_t supports_sync_fd; /* OUT */
155+
uint32_t supports_semsurf; /* OUT */
156+
};
157+
158+
139159
struct drm_nvidia_fence_context_create_params {
140160
uint32_t handle; /* OUT GEM handle to fence context */
141161

src/direct/nv-driver.c

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -190,20 +190,43 @@ static bool nv0_register_fd(int nv0_fd, int nvctl_fd) {
190190
return true;
191191
}
192192

193-
static bool get_device_info(int fd, struct drm_nvidia_get_dev_info_params *devInfo) {
194-
int ret = ioctl(fd, DRM_IOCTL_NVIDIA_GET_DEV_INFO, devInfo);
193+
static bool get_device_info(int fd, NVDriverContext *context) {
194+
//NVIDIA driver v545.29.02 changed the devInfo struct, and partly broke it in the process
195+
//...who adds a field to the middle of an existing struct....
196+
if (context->driverMajorVersion >= 545 && context->driverMinorVersion >= 29) {
197+
struct drm_nvidia_get_dev_info_params_545 devInfo545;
198+
int ret = ioctl(fd, DRM_IOCTL_NVIDIA_GET_DEV_INFO_545, &devInfo545);
199+
200+
if (ret != 0) {
201+
LOG("get_device_info failed: %d %d", ret, errno);
202+
return false;
203+
}
195204

196-
if (ret != 0) {
197-
LOG("get_device_info failed: %d %d", ret, errno);
198-
return false;
205+
context->gpu_id = devInfo545.gpu_id;
206+
context->sector_layout = devInfo545.sector_layout;
207+
context->page_kind_generation = devInfo545.page_kind_generation;
208+
context->generic_page_kind = devInfo545.generic_page_kind;
209+
} else {
210+
struct drm_nvidia_get_dev_info_params devInfo;
211+
int ret = ioctl(fd, DRM_IOCTL_NVIDIA_GET_DEV_INFO, &devInfo);
212+
213+
if (ret != 0) {
214+
LOG("get_device_info failed: %d %d", ret, errno);
215+
return false;
216+
}
217+
218+
context->gpu_id = devInfo.gpu_id;
219+
context->sector_layout = devInfo.sector_layout;
220+
context->page_kind_generation = devInfo.page_kind_generation;
221+
context->generic_page_kind = devInfo.generic_page_kind;
199222
}
200223

201224
return true;
202225
}
203226

204227
bool get_device_uuid(NVDriverContext *context, char uuid[16]) {
205228
NV0000_CTRL_GPU_GET_UUID_FROM_GPU_ID_PARAMS uuidParams = {
206-
.gpuId = context->devInfo.gpu_id,
229+
.gpuId = context->gpu_id,
207230
.flags = NV0000_CTRL_CMD_GPU_GET_UUID_FROM_GPU_ID_FLAGS_FORMAT_BINARY |
208231
NV0000_CTRL_CMD_GPU_GET_UUID_FROM_GPU_ID_FLAGS_TYPE_SHA1
209232
};
@@ -221,12 +244,6 @@ bool get_device_uuid(NVDriverContext *context, char uuid[16]) {
221244

222245
bool init_nvdriver(NVDriverContext *context, int drmFd) {
223246
LOG("Initing nvdriver...");
224-
if (!get_device_info(drmFd, &context->devInfo)) {
225-
return false;
226-
}
227-
228-
LOG("Got dev info: %x %x %x %x", context->devInfo.gpu_id, context->devInfo.sector_layout, context->devInfo.page_kind_generation, context->devInfo.generic_page_kind);
229-
230247
int nvctlFd = -1, nv0Fd = -1;
231248

232249
nvctlFd = open("/dev/nvidiactl", O_RDWR|O_CLOEXEC);
@@ -243,9 +260,16 @@ bool init_nvdriver(NVDriverContext *context, int drmFd) {
243260
char *ver = NULL;
244261
nv_get_versions(nvctlFd, &ver);
245262
context->driverMajorVersion = atoi(ver);
246-
LOG("NVIDIA kernel driver version: %s, major version: %d", ver, context->driverMajorVersion);
263+
context->driverMinorVersion = atoi(ver+4);
264+
LOG("NVIDIA kernel driver version: %s, major version: %d, minor version: %d", ver, context->driverMajorVersion, context->driverMinorVersion);
247265
free(ver);
248266

267+
if (!get_device_info(drmFd, context)) {
268+
return false;
269+
}
270+
271+
LOG("Got dev info: %x %x %x %x", context->gpu_id, context->sector_layout, context->page_kind_generation, context->generic_page_kind);
272+
249273
//allocate the root object
250274
bool ret = nv_alloc_object(nvctlFd, context->driverMajorVersion, NULL_OBJECT, NULL_OBJECT, &context->clientObject, NV01_ROOT_CLIENT, 0, (void*)0);
251275
if (!ret) {
@@ -254,7 +278,7 @@ bool init_nvdriver(NVDriverContext *context, int drmFd) {
254278
}
255279

256280
//attach the drm fd to this handle
257-
ret = nv_attach_gpus(nvctlFd, context->devInfo.gpu_id);
281+
ret = nv_attach_gpus(nvctlFd, context->gpu_id);
258282
if (!ret) {
259283
LOG("nv_attach_gpu failed");
260284
goto err;
@@ -372,7 +396,7 @@ bool alloc_memory(NVDriverContext *context, uint32_t size, int *fd) {
372396
}
373397

374398
//attach the new fd to the correct gpus
375-
ret = nv_attach_gpus(nvctlFd2, context->devInfo.gpu_id);
399+
ret = nv_attach_gpus(nvctlFd2, context->gpu_id);
376400
if (!ret) {
377401
LOG("nv_attach_gpus failed");
378402
goto err;
@@ -499,7 +523,7 @@ bool alloc_image(NVDriverContext *context, uint32_t width, uint32_t height, uint
499523
image->nvFd = memFd;
500524
image->nvFd2 = memFd2; //not sure why we can't close this one, we shouldn't need it after importing the image
501525
image->drmFd = prime_handle.fd;
502-
image->mods = DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, context->devInfo.sector_layout, context->devInfo.page_kind_generation, context->devInfo.generic_page_kind, log2GobsPerBlockY);
526+
image->mods = DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, context->sector_layout, context->page_kind_generation, context->generic_page_kind, log2GobsPerBlockY);
503527
image->offset = 0;
504528
image->pitch = widthInBytes;
505529
image->memorySize = imageSizeInBytes;

src/direct/nv-driver.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@ typedef struct {
1212
int nvctlFd;
1313
int nv0Fd;
1414
int drmFd;
15-
struct drm_nvidia_get_dev_info_params devInfo;
1615
uint32_t clientObject;
1716
uint32_t deviceObject;
1817
uint32_t subdeviceObject;
1918
uint32_t driverMajorVersion;
19+
uint32_t driverMinorVersion;
2020
//bool hasHugePage;
21+
uint32_t gpu_id;
22+
uint32_t generic_page_kind;
23+
uint32_t page_kind_generation;
24+
uint32_t sector_layout;
2125
} NVDriverContext;
2226

2327
typedef struct {

0 commit comments

Comments
 (0)