Оригинальный вопрос: я пытаюсь написать трассировщик пути на C++ с использованием CUDA. Сейчас я нахожусь на этапе, когда я пытаюсь передать массив фигур в функцию рендеринга, но даже хотя они были скопированы в память устройства, я получаю нелегальное сообщение доступ к памяти при попытке доступа к методам фигур. Возможно, это связано с тем, как я структурирую классы и их наследование.
У меня есть основная функция рендеринга, которая принимает dscriptor сцены и массив изображений
У меня есть функция рендеринга хоста, которая принимает dscriptor сцены и массив изображений
p>
Код: Выделить всё
__host__ void render(const std::shared_ptr &scene, uchar4 *image);
Код: Выделить всё
__global__ void renderImage(const uint16_t width, const uint16_t height,
uchar4 *image, const Vec3 origin,
const Vec3 pixel00, const Vec3 deltaU,
const Vec3 deltaV, const Shape **shapes,
const size_t num_shapes);
Код: Выделить всё
// shape.cuh
#pragma once
#include "cuda_path_tracer/ray.cuh"
class Shape {
public:
Shape() = default;
Shape(const Shape &) = default;
__host__ __device__ Shape(Shape &&) = delete;
auto operator=(const Shape &) -> Shape & = default;
__host__ __device__ auto operator=(Shape &&) -> Shape & = delete;
virtual ~Shape() = default;
__host__ __device__ virtual auto hit(const Ray &r) const -> bool = 0;
__host__ __device__ virtual auto getShapeType() const -> ShapeType = 0;
};
Код: Выделить всё
// sphere.cuh
#pragma once
#include "shape.cuh"
class Sphere : public Shape {
public:
__host__ __device__ Sphere(const Vec3 ¢er, float radius);
__host__ __device__ auto hit(const Ray &r) const -> bool override;
__host__ __device__ auto hitt() const -> bool override;
__host__ __device__ auto getShapeType() const -> ShapeType override;
private:
Vec3 center;
float radius;
};
Код: Выделить всё
// sphere.cu
#include "cuda_path_tracer/sphere.cuh"
__host__ Sphere::Sphere(const Vec3 ¢er, const float radius)
: Shape(), center(center), radius(radius) {}
__host__ __device__ auto Sphere::hit(const Ray &r) const -> bool {
Vec3 const oc = r.getOrigin() - center;
float const a = r.getDirection().dot(r.getDirection());
float const b = 2.0f * oc.dot(r.getDirection());
float const c = oc.dot(oc) - radius * radius;
float const discriminant = b * b - 4 * a * c;
return discriminant > 0;
}
Код: Выделить всё
const auto num_shapes = scene->getShapes().size();
const Shape **d_shapes;
CUDA_ERROR_CHECK(
cudaMalloc((void **)&d_shapes, num_shapes * sizeof(Shape *)));
Shape **h_shapes = new Shape *[num_shapes];
for (size_t i = 0; i < num_shapes; i++) {
CUDA_ERROR_CHECK(cudaMalloc((void **)&h_shapes[i], sizeof(Shape)));
CUDA_ERROR_CHECK(cudaMemcpy(h_shapes[i], scene->getShapes()[i],
sizeof(Shape), cudaMemcpyHostToDevice));
}
CUDA_ERROR_CHECK(cudaMemcpy(d_shapes, h_shapes, num_shapes * sizeof(Shape *),
cudaMemcpyHostToDevice));
delete[] h_shapes;
Код: Выделить всё
__device__ auto getColor(const Ray &ray, const Shape *const *shapes,
const size_t num_shapes) -> uchar4 {
// Dummy implementation
for (size_t i = 0; i < num_shapes; i++) {
if (shapes[i]->hit(ray)) {
return make_uchar4(1, 0, 0, UCHAR_MAX);
}
}
return make_uchar4(0, 0, 1, UCHAR_MAX);
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... -cuda-in-c
Мобильная версия