⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bsapi.h

📁 Ray tracing on PS3, using the acceleration of PPU, No SPE acceleration is used. The code must be com
💻 H
字号:
/* Copyright (c) 2007 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//** * bsapi.h - blue-steel API definitions * @author Brian Sweatt  * * Contains methods that are to be exposed to the user on the PPU for initializing the ray tracing engine, * as well as setting viewing parameters, and rendering the image asynchronously to the PPU program. *  * This file cannot be included in SPU programs. * The simplified user interface API is specified towards the end of the file. * The bulk of the methods at the top are used for sending messages to the SPU ray tracing program. Most * users will not need to utilize these methods directly. */#ifndef _BSAPI_H_#define _BSAPI_H_extern "C" {  #include <libspe.h>}extern spe_program_handle_t spu_raytracer;typedef struct {  speid_t id;  spe_spu_control_area_t *control_ps_area;} spe_info_t;spe_info_t rendering_spe[TOTAL_SPES];/** * Send a render scene message to the spe specified by spe_num * Waits until all 4 in_mbox spots are open, then sends: * 1) The SPE_RENDER_REGION opcode * 2) The memory location to store the rendered scene to * 3) The starting x-coordinate of the region to render * 4) The starting y-coordinate of the region to render * It then waits for another 2 spots to open and sends: * 5) The width of the region to render * 6) The height of the region to render */inline void send_spe_render_region(int spe_num, uint32_t addr, uint32_t startx, uint32_t starty) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 4){dprintf("(PPE)Waiting on (%i)\n", spe_num);}  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_RENDER_REGION);  spe_write_in_mbox(rendering_spe[spe_num].id, addr);  spe_write_in_mbox(rendering_spe[spe_num].id, startx);  spe_write_in_mbox(rendering_spe[spe_num].id, starty);}    /** * Sends a read scene message to the spe specified by spe_num * waits until 3 in_mbox spots are open, then sends: * 1) The SPE_READ_SCENE opcode * 2) The memory location of the start of the object array * 3) The number of objects to load from the object array */inline void send_spe_read_scene(int spe_num, uint32_t addr, uint32_t num_objs) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 3);  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_READ_SCENE);  spe_write_in_mbox(rendering_spe[spe_num].id, addr);  spe_write_in_mbox(rendering_spe[spe_num].id, num_objs);}/** * Sends an update camera message to the spe specified by spe_num * Waits until 2 in_mbox spots are open, then sends: * 1) The SPE_UPDATE_CAMERA opcode * 2) The memory location of a CameraControl structure */inline void send_spe_update_camera(int spe_num, uint32_t cc_addr) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 2);  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_UPDATE_CAMERA);  spe_write_in_mbox(rendering_spe[spe_num].id, cc_addr);}/** * Sends a update camera position message to the spe specified by spe_num * Waits until all 4 in_mbox spots are open, then sends: * 1) The SPE_UPDATE_CAMERA_POS opcode * 2) The new x coordinate for the camera * 3) The new y coordinate for the camera * 4) The new z coordinate for the camera */inline void send_spe_update_camera_pos(int spe_num, float newX, float newY, float newZ) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 4);   spe_write_in_mbox(rendering_spe[spe_num].id, SPE_UPDATE_CAMERA_POS);  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(newX));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(newY));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(newZ));}    /** * Sends a update ball 1 position message to the spe specified by spe_num * Waits until all 4 in_mbox spots are open, then sends: * 1) The SPE_UPDATE_BALL1 opcode * 2) The new x coordinate for the ball * 3) The new y coordinate for the ball * 4) The new z coordinate for the ball */inline void send_spe_update_ball1(int spe_num, float newX, float newY, float newZ) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 4);  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_UPDATE_BALL1);  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(newX));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(newY));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(newZ));}  /** * Sends a message to an spe to splat a region with an RGB color * Waits until 4 in_mbox spots are open, then sends: * 1) The SPE_SPLAT_REGION opcode * 2) The address of the region to be splatted * 3) The width of the region to be splatted * 4) The height of the region to be splatted * It then waits for 3 spots to open up, and sends  * 5) The R value of the splat color * 6) The G value of the splat color * 7) The B value of the splat color */inline void send_spe_splat_region(int spe_num, uint32_t addr, uint32_t width, uint32_t height,			   float R, float G, float B) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 4);  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_SPLAT_REGION);  spe_write_in_mbox(rendering_spe[spe_num].id, addr);  spe_write_in_mbox(rendering_spe[spe_num].id, width);  spe_write_in_mbox(rendering_spe[spe_num].id, height);  dprintf("(PPE)Finished first splat_region delivery to (%i)\n", spe_num);  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 3){dprintf("(PPE)Waiting on (%i)\n", spe_num);}  dprintf("(PPE)Done waiting on splat spots to open on (%i)\n", spe_num);  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(R));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(G));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(B));}   /** * Sends a message to an spe to update the number of spheres it can havex * Waits for 2 in_mbox spots to open, then sends: * 1) The SPE_SET_NUM_SPHERES opcode * 2) The new number of spheres the spe can have */inline void send_spe_set_num_spheres(int spe_num, uint32_t num_spheres) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 2);  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_SET_NUM_SPHERES);  spe_write_in_mbox(rendering_spe[spe_num].id, num_spheres);}/** * Sends a message to an spe telling it to add a sphere to it's object array * Waits for 4 in_mbox spots to open, then sends: * 1) The SPE_ADD_SPHERE opcode * 2, 3, 4) The x, y, and z coordinates for the sphere * It then waits for 2 in_mbox spots to open up, and sends: * 5) The radius of the sphere * 6) The material id of the sphere */inline void send_spe_add_sphere(int spe_num, float x, float y, float z, float r, uint32_t m_id) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 4);  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_ADD_SPHERE);  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(x));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(y));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(z));  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 2);  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(r));  spe_write_in_mbox(rendering_spe[spe_num].id, m_id);}inline void send_spe_set_num_triangles(int spe_num, uint32_t num_triangles) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 2);  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_SET_NUM_TRIANGLES);  spe_write_in_mbox(rendering_spe[spe_num].id, num_triangles);}inline void send_spe_add_triangle(int spe_num, float ax, float ay, float az,			   float bx, float by, float bz, float cx, float cy, float cz, uint32_t m_id) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 4);  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_ADD_TRIANGLE);  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(ax));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(ay));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(az));  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 3);  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(bx));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(by));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(bz));  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 4);  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(cx));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(cy));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(cz));  spe_write_in_mbox(rendering_spe[spe_num].id, m_id);}inline void send_spe_set_num_spes(int spe_num, uint32_t stride) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 2);  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_SET_NUM_SPES);  spe_write_in_mbox(rendering_spe[spe_num].id, stride);}/** * Sends the address of an ObjectSet object containing pointers to the objects in the scene * Waits until two mailbox slots open up, then sends: * 1) The SPE_GET_OBJECTSET opcode * 2) The address of the ObjectSet to DMA from main memory (as a uint32_t) */inline void send_spe_init_raytracer(int spe_num, ObjectSet *objects) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 2);  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_INIT_RAYTRACER);  spe_write_in_mbox(rendering_spe[spe_num].id, (uint32_t) objects);}inline void send_spe_set_ambient(int spe_num, float r, float g, float b) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 4);  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_SET_AMBIENT);  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(r));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(g));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(b));}inline void send_spe_look_at(int spe_num, float x, float y, float z,			     float ux, float uy, float uz) {  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 4);  spe_write_in_mbox(rendering_spe[spe_num].id, SPE_LOOK_AT);  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(x));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(y));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(z));  while (spe_stat_in_mbox(rendering_spe[spe_num].id) < 4);  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(ux));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(uy));  spe_write_in_mbox(rendering_spe[spe_num].id, float_as_uint32(uz));}//////////////////////////////////////////////////////// Simplified user interface methods for blue-steel /////////////////////////////////////////////////////////** * Called to initialize the SPU ray tracer with the current number of SPUs defined in common.h * As well as the ObjectSet being passed in to represent the scene to be rendered * Subsequent calls to bsRenderScene will use this ObjectSet to render the scene * @param objects A pointer to the ObjectSet representing the scene to be rendered */inline void bsInit(ObjectSet *objects) {  for (int i = 0; i < NUM_RENDERING_SPES; i++) {    rendering_spe[i].id = spe_create_thread(0, &spu_raytracer, (void *)i, NULL, -1, 0);  }  for (int i = 0; i < NUM_RENDERING_SPES; i++) {    send_spe_init_raytracer(i, objects);    send_spe_set_num_spes(i, NUM_RENDERING_SPES);  }}/** * Tells the SPU raytracer to start the asynchronous rendering process for the current scene * Please note: The image buffer being passed in must have the dimensions specified in common.h * @param image An array of vector unsigned ints that will hold the image data for the rendered scene */inline void bsRenderScene(vector unsigned int *image) {  for (int i = 0; i < NUM_RENDERING_SPES; i++) {    send_spe_render_region(i,(uint32_t) &image[STRIP_WIDTH*i], 0, i);  }}/** * Given a point in space to look at, as well as direction that will be considered as 'up' * This method sets the Camera in the ray tracer to look at the given point. * @param x The x-coordinate of the point for the camera to look at * @param y The y-coordinate of the point for the camera to look at * @param z The z-coordinate of the point for the camera to look at * @param ux The component of the up direction in the unit x direction * @param ux The component of the up direction in the unit y direction * @param ux The component of the up direction in the unit z direction */inline void bsLookAt(float x, float y, float z, float ux, float uy, float uz) {  for (int i = 0; i < NUM_RENDERING_SPES; i++) {    send_spe_look_at(i, x, y, z, ux, uy, uz);  }}/** * Sets the position of the center of the camera, to be applied to the next frame rendered. * @param x The x-coordinate of the new center of the camera * @param y The y-coordinate of the new center of the camera * @param z The z-coordinate of the new center of the camera */ inline void bsSetCenter(float x, float y, float z) {  for (int i = 0; i < NUM_RENDERING_SPES; i++) {    send_spe_update_camera_pos(i, x, y, z);  }}/** * Sets the ambient lighting to be used in the rendered image * This is a faked constant ambient illumination * @param r The red component of the ambient lighting to be applied * @param g The green component of the ambient lighting to be applied * @param b The blue component of the ambient lighting to be applied */inline void bsAmbient(float r, float g, float b) {  for (int i = 0; i < NUM_RENDERING_SPES; i++) {    send_spe_set_ambient(i, r, g, b);  }}/** * Waits for the current rendering to finish. Upon return, the image buffer passed in * to bsRenderScene will be filled with the completed rendering of the scene */inline void bsWait() {  for (int i = 0; i < NUM_RENDERING_SPES; i++) {    while (spe_stat_out_mbox(rendering_spe[i].id) == 0);    spe_read_out_mbox(rendering_spe[i].id);  }}/** * Checks whether the last rendering operation has completed. * This method returns true if it has, false otherwise */inline bool bsDone() {  for (int i = 0; i < NUM_RENDERING_SPES; i++) {    if (spe_stat_out_mbox(rendering_spe[i].id) == 0)      return false;  }  return true;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -