gfx-rs / wgpu-native

Native WebGPU implementation based on wgpu-core
Apache License 2.0
843 stars 96 forks source link

Releasing any WGPUQueue destroys all WGPUQueues #356

Closed PyryM closed 7 months ago

PyryM commented 7 months ago

E.g., just doing this:

{
    WGPUQueue temp = wgpuDeviceGetQueue(device);
    wgpuQueueRelease(temp);
}

will cause usage of any other queue from that device to fail with something like

thread '<unnamed>' panicked at C:\Users\runneradmin\.cargo\git\checkouts\wgpu-53e70f8674b08dd4\b8a8ff6\wgpu-core\src\storage.rs:113:39:
Queue[Id(0,1,vk)] does not exist

I suspect this is related/the same underlying issue as https://github.com/gfx-rs/wgpu/issues/5092

Reproducer:

#include "webgpu.h"
#include "wgpu.h"
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

typedef struct Demo {
  WGPUInstance instance;
  WGPUAdapter adapter;
  WGPUDevice device;
} Demo;

static void handle_request_adapter(WGPURequestAdapterStatus status,
                                   WGPUAdapter adapter, char const *message,
                                   void *userdata) {
  if (status == WGPURequestAdapterStatus_Success) {
    Demo* demo = userdata;
    demo->adapter = adapter;
  } else {
    printf("request_adapter status=%#.8x message=%s\n", status, message);
  }
}

static void handle_request_device(WGPURequestDeviceStatus status,
                                  WGPUDevice device, char const *message,
                                  void *userdata) {
  if (status == WGPURequestDeviceStatus_Success) {
    Demo* demo = userdata;
    demo->device = device;
  } else {
    printf("request_device status=%#.8x message=%s\n", status, message);
  }
}

int main(int argc, char *argv[]) {
  Demo demo = {0};
  demo.instance = wgpuCreateInstance(NULL);
  assert(demo.instance);

  WGPURequestAdapterOptions options = {0};
  wgpuInstanceRequestAdapter(demo.instance, &options, handle_request_adapter, &demo);
  assert(demo.adapter);

  wgpuAdapterRequestDevice(demo.adapter, NULL, handle_request_device, &demo);
  assert(demo.device);

  WGPUQueue queue = wgpuDeviceGetQueue(demo.device);
  assert(queue);

  if(argc <= 1) {
    printf("Only getting one queue; this should complete normally!\n");
  } else {
    printf("Requesting & releasing another queue!\n");
    WGPUQueue queue2 = wgpuDeviceGetQueue(demo.device);
    wgpuQueueRelease(queue2);
  }

  WGPUBufferDescriptor buff_desc = {.usage = WGPUBufferUsage_CopyDst, .size = 256};
  WGPUBuffer buff = wgpuDeviceCreateBuffer(demo.device, &buff_desc);
  uint8_t data[256] = {0};
  wgpuQueueWriteBuffer(queue, buff, 0, data, 256);

  printf("Done without panic!\n");

  return 0;
}
rajveermalviya commented 7 months ago

I suspect this is related/the same underlying issue as https://github.com/gfx-rs/wgpu/issues/5092

That seems unrelated, it was bug in wgpu-native which #357 fixes.