📄 spu_raytracer.cpp
字号:
float uy = uint32_as_float(spu_read_in_mbox()); float uz = uint32_as_float(spu_read_in_mbox()); render_context.camera->setDirection((vector float) {x,y,z,0}, (vector float) {ux, uy, uz, 0});}void handle_spe_look_at(ObjectSet *objects, RenderContext &render_context, RayTracer *rt, vector unsigned int image_buf[2][STRIP_SIZE], ObjectSet *obj_ea) { float x = uint32_as_float(spu_read_in_mbox()); float y = uint32_as_float(spu_read_in_mbox()); float z = uint32_as_float(spu_read_in_mbox()); float ux = uint32_as_float(spu_read_in_mbox()); float uy = uint32_as_float(spu_read_in_mbox()); float uz = uint32_as_float(spu_read_in_mbox()); vector float dir = (vector float) {x,y,z,0}; vector float up = (vector float) {ux, uy, uz, 0}; dir = spu_sub(dir, render_context.camera->getCenter()); render_context.camera->setDirection(dir, up);}// WARNING: This code no longer works with the new DMAing frame work - it is left for compatibility void handle_spe_set_num_spheres(ObjectSet *objects, RenderContext &render_context, RayTracer *rt, vector unsigned int image_buf[2][STRIP_SIZE], ObjectSet *obj_ea) { //objects->max_spheres = spu_read_in_mbox(); if (objects->spheres) free_align(objects->spheres); //objects->spheres = (Sphere *) malloc_align(objects->max_spheres * sizeof(Sphere), 7); objects->num_spheres = 0;}// WARNING: No longer works with DMA systemvoid handle_spe_add_sphere(ObjectSet *objects, RenderContext &render_context, RayTracer *rt, vector unsigned int image_buf[2][STRIP_SIZE], ObjectSet *obj_ea) { float x = uint32_as_float(spu_read_in_mbox()); float y = uint32_as_float(spu_read_in_mbox()); float z = uint32_as_float(spu_read_in_mbox()); float rad = uint32_as_float(spu_read_in_mbox()); uint32_t curr_m = spu_read_in_mbox(); dprintf("(%i)Adding sphere #%i: %f %f %f %f\n", spe_num, objects->num_spheres+1, x,y,z,rad); objects->spheres[objects->num_spheres] = Sphere(load_vec_float4(x,y,z,rad), curr_m); objects->num_spheres++;}// WARNING: No longer works with DMA systemvoid handle_spe_set_num_triangles(ObjectSet *objects, RenderContext &render_context, RayTracer *rt, vector unsigned int image_buf[2][STRIP_SIZE], ObjectSet *obj_ea) { //objects->max_triangles = spu_read_in_mbox(); if (objects->triangles) free_align(objects->triangles); //objects->triangles = (Triangle *) malloc_align(objects->max_triangles * sizeof(Triangle), 7); objects->num_triangles = 0;}// WARNING: No longer works with DMA system... void handle_spe_add_triangle(ObjectSet *objects, RenderContext &render_context, RayTracer *rt, vector unsigned int image_buf[2][STRIP_SIZE], ObjectSet *obj_ea) { vector float a = load_vec_float4(uint32_as_float(spu_read_in_mbox()), uint32_as_float(spu_read_in_mbox()), uint32_as_float(spu_read_in_mbox()), 0.0f); vector float b = load_vec_float4(uint32_as_float(spu_read_in_mbox()), uint32_as_float(spu_read_in_mbox()), uint32_as_float(spu_read_in_mbox()), 0.0f); vector float c = load_vec_float4(uint32_as_float(spu_read_in_mbox()), uint32_as_float(spu_read_in_mbox()), uint32_as_float(spu_read_in_mbox()), 0.0f); uint32_t curr_m = spu_read_in_mbox(); objects->triangles[objects->num_triangles] = Triangle(a,b,c,curr_m); //For now, we're ignoring normals/textures objects->num_triangles++;}void handle_spe_set_num_spes(ObjectSet *objects, RenderContext &render_context, RayTracer *rt, vector unsigned int image_buf[2][STRIP_SIZE], ObjectSet *obj_ea) { render_context.stride = spu_read_in_mbox();}void handle_spe_set_ambient(ObjectSet *objects, RenderContext &render_context, RayTracer *rt, vector unsigned int image_buf[2][STRIP_SIZE], ObjectSet *obj_ea) { float r = uint32_as_float(spu_read_in_mbox()); float g = uint32_as_float(spu_read_in_mbox()); float b = uint32_as_float(spu_read_in_mbox()); rt->setAmbient((vector float) {r,g,b});}/** * NOTE: This method starts a DMA with DMA_TAG_OBJECTSET as the tag. The resulting data is stored in the obj_ea * pointer, whose data members will contain the ea's of the object arrays to DMA from. This data should be DMA'd * into the objects pointer for use in the RayTracer class. The num_ fields of obj_ea will be filled in with the * correct values for the numbers of primitives. * * This method blocks until the aforementioned DMA transfer has completed. It then allocates the * objects in objects according to the sizes returned in obj_ea. * * The ea's of the object arrays should not change throughout the program and the number of primitives * should also remain constant. As a result, blocking, as well as the branches from rampant if statements * are feasible since this method should only be called once. */void handle_spe_init_raytracer(ObjectSet *objects, RenderContext &render_context, RayTracer *rt, vector unsigned int image_buf[2][STRIP_SIZE], ObjectSet *obj_ea) { uint32_t addr = (uint32_t) spu_read_in_mbox(); if (obj_ea) { free_align(obj_ea); } obj_ea = (ObjectSet *) malloc_align(sizeof(ObjectSet), 7); mfc_get((void *)obj_ea, addr, sizeof(ObjectSet), DMA_TAG_OBJECTSET,0,0); if (objects) { free_align(objects); } mfc_write_tag_mask(1 << DMA_TAG_OBJECTSET); // block until the DMA has completed mfc_read_tag_status_all(); uint32_t sizeOfLights = sizeof(light)*obj_ea->num_lights; uint32_t sizeOfMaterials = sizeof(material)*obj_ea->num_materials; objects = (ObjectSet *) malloc_align(sizeof(ObjectSet), 7); objects->num_spheres = obj_ea->num_spheres; objects->num_triangles = obj_ea->num_triangles; objects->spheres = (Sphere *) malloc_align(sizeof(Sphere)*(objects->num_spheres), 7); objects->triangles = (Triangle *) malloc_align(sizeof(Triangle)*(objects->num_triangles), 7); objects->num_materials = obj_ea->num_materials; objects->num_lights = obj_ea->num_lights; objects->materials = (material *) malloc_align(sizeOfMaterials, 7); objects->lights = (light *) malloc_align(sizeOfLights, 7); mfc_get((void *) objects->materials, obj_ea->materials, sizeOfMaterials, DMA_TAG_MATERIALS, 0, 0); mfc_get((void *) objects->lights, obj_ea->lights, sizeOfLights, DMA_TAG_LIGHTS, 0, 0); if (rt) { free_align(rt); } rt = (RayTracer *) malloc_align(sizeof(RayTracer), 7); rt[0] = RayTracer(objects, MAX_BOUNCES, false, 1, (vector float) {0.00f, 0.00f, 0.00f, 0.00f}); }int main(uint64_t speid, uint64_t argp, uint64_t envp) { dprintf("spu_raytracer: main()\r\n"); // Each spu is aware of its spe_num on the PPE... spe_num = argp; // Initialize array of pointers to opcode handlers opcode_handler[SPE_NOP] = &handle_spe_nop; opcode_handler[SPE_RENDER_REGION] = &handle_spe_render_region; opcode_handler[SPE_READ_SCENE] = &handle_spe_read_scene; opcode_handler[SPE_SET_NUM_SPHERES] = &handle_spe_set_num_spheres; opcode_handler[SPE_ADD_SPHERE] = &handle_spe_add_sphere; opcode_handler[SPE_SET_NUM_TRIANGLES] = &handle_spe_set_num_triangles; opcode_handler[SPE_ADD_TRIANGLE] = &handle_spe_add_triangle; opcode_handler[SPE_SET_NUM_SPES] = &handle_spe_set_num_spes; opcode_handler[SPE_UPDATE_CAMERA] = &handle_spe_nop; opcode_handler[SPE_UPDATE_CAMERA_POS] = &handle_spe_update_camera_pos; opcode_handler[SPE_UPDATE_BALL1] = &handle_spe_nop; opcode_handler[SPE_SPLAT_RGB] = &handle_spe_nop; opcode_handler[SPE_SPLAT_REGION] = &handle_spe_nop; opcode_handler[SPE_SET_NUM_PLANES] = &handle_spe_nop; opcode_handler[SPE_ADD_PLANE] = &handle_spe_nop; opcode_handler[SPE_TRANSLATE_SPHERE] = &handle_spe_nop; opcode_handler[SPE_INIT_RAYTRACER] = &handle_spe_init_raytracer; opcode_handler[SPE_UPDATE_CAMERA_DIR] = &handle_spe_update_camera_dir; opcode_handler[SPE_LOOK_AT] = &handle_spe_look_at; opcode_handler[SPE_SET_AMBIENT] = &handle_spe_set_ambient; unsigned int opcode = SPE_NOP; uint32_t scene_size; // Set up the rendering context to be used when rendering the scene // The remaining values for this object that are not filled in now will be filled in when // the ray tracer is initialized and the number of SPEs is set. RenderContext render_context; render_context.region_width = IMG_WIDTH; render_context.region_height = 1; render_context.stride = NUM_RENDERING_SPES; render_context.total_width = IMG_WIDTH; render_context.total_height = IMG_HEIGHT; render_context.startx = render_context.starty = 0; // Simple default values for the camera... the user is expected to change these before use // or their scene will probably not be in the viewport. render_context.camera = new Camera(load_vec_float4(1.0f, -0.50f, 1.5f, 0.0f), load_vec_float4(0.0f, 1.0f, 0.0f, 0.0f), load_vec_float4(0.01f, 0.01f, 1.0f, 0.0f), 1.0f); ObjectSet *objects = (ObjectSet *) malloc_align(sizeof(ObjectSet), 7); ObjectSet *obj_ea = (ObjectSet *) malloc_align(sizeof(ObjectSet), 7); RayTracer *rt = (RayTracer *) malloc_align(sizeof(RayTracer), 7); *(rt) = RayTracer(objects, MAX_BOUNCES, false, 1, (vector float) {0.5f, 0.5f, 0.5f, 0.5f}); RGBPacket splat_color; vector unsigned int image_buf[2][STRIP_SIZE] __attribute__((aligned(128))); while (1) { opcode = spu_read_in_mbox() % NUM_OPCODES; opcode_handler[opcode](objects, render_context, rt, image_buf, obj_ea); //printf("Opcode received: triangles addr: %u\n", obj_ea->triangles); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -