void GenerateFrustum() { // g_R2OCon.m_frustum_planes has 6 planes in the following order: // // 0: near (there is igg code that assumes this is first) // 1: left // 2: right // 3: bottom // 4: top // 5: far (there is igg code that assumes this is last) // the plane normals point into the interior of the frustum // copy T,B,L,R planes directly for (u32 i=1; i<5; i++) { g_Planes[i] = g_pViewData->m_frustum_planes[i]; // loosen frustum based on lod, amplitude, and a fudgefactor f32 nw = spu_extract(g_Planes[i], 3); f32 ny = spu_extract(g_Planes[i], 1); //f32 slop = g_R2OCon.m_frustum_fudge_factor * g_WaterObject.m_amplitude * powf(0.5f, 0.5f*(f32)lod) // * (g_R2OCon.m_step * 0.0625f); // readjust based on changed in lod 0 from 16m to 128m stepsize //f32 slop = g_R2OCon.m_frustum_fudge_factor * powf(0.5f, 0.5f*(f32)lod); f32 slop = g_R2OCon.m_frustum_fudge_factor * step; nw += slop * fabsf(ny); g_Planes[i] = spu_insert(nw, g_Planes[i], 3); } // compute near subfrustum plane based on lod //f32 d = g_R2OCon.m_near0 * powf(0.5f, 0.5f*(f32)lod); f32 d = g_R2OCon.m_near0 * step * (1.0f/128.0f); // test if (lod==g_R2OCon.m_num_lods-1) { d = step; } vf32 camera_direction = (vf32){0,0,1,0}; camera_direction = spu_insert(g_pViewData->m_world_to_camera_matrix.m_v0.z, camera_direction, 0); camera_direction = spu_insert(g_pViewData->m_world_to_camera_matrix.m_v1.z, camera_direction, 1); camera_direction = spu_insert(g_pViewData->m_world_to_camera_matrix.m_v2.z, camera_direction, 2); f32 dot = spu_extract(spu_dot3(camera_direction, g_pViewData->m_camera_position), 0); f32 w = -(dot + d); g_Planes[0] = spu_insert(w, camera_direction, 3); // reverse the sense of the near plane g_Planes[0] = -g_Planes[0]; }
vec_ullong2 bitDiff_d2(vec_double2 ref, vec_double2 vals) { double ref0, ref1, vals0, vals1; long long refi0, refi1, valsi0, valsi1, diff0, diff1; vec_ullong2 bits; ref0 = spu_extract(ref,0); ref1 = spu_extract(ref,1); vals0 = spu_extract(vals,0); vals1 = spu_extract(vals,1); refi0 = make_ulonglong(ref0); refi1 = make_ulonglong(ref1); valsi0 = make_ulonglong(vals0); valsi1 = make_ulonglong(vals1); diff0 = refi0 - valsi0; diff1 = refi1 - valsi1; if ( diff0 < 0 ) { diff0 = valsi0 - refi0; } if ( diff1 < 0 ) { diff1 = valsi1 - refi1; } bits = spu_promote( (unsigned long long)ceil(log2((double)diff0)), 0 ); bits = spu_insert( (unsigned long long)ceil(log2((double)diff1)), bits, 1 ); return bits; }
vec_ullong2 ulpDiff_d2(vec_double2 ref, vec_double2 vals) { double ref0, ref1, vals0, vals1; long long refi0, refi1, valsi0, valsi1, diff0, diff1; vec_ullong2 ulps; ref0 = spu_extract(ref,0); ref1 = spu_extract(ref,1); vals0 = spu_extract(vals,0); vals1 = spu_extract(vals,1); refi0 = make_ulonglong(ref0); refi1 = make_ulonglong(ref1); valsi0 = make_ulonglong(vals0); valsi1 = make_ulonglong(vals1); diff0 = refi0 - valsi0; diff1 = refi1 - valsi1; if ( diff0 < 0 ) { diff0 = valsi0 - refi0; } if ( diff1 < 0 ) { diff1 = valsi1 - refi1; } ulps = spu_promote( (unsigned long long)diff0, 0 ); ulps = spu_insert( (unsigned long long)diff1, ulps, 1 ); return ulps; }
void * sbrk (ptrdiff_t increment) { static caddr_t heap_ptr = NULL; caddr_t base; vector unsigned int sp_reg, sp_delta; vector unsigned int *sp_ptr; caddr_t sps; /* The stack pointer register. */ volatile register vector unsigned int sp_r1 __asm__("1"); if (heap_ptr == NULL) heap_ptr = (caddr_t) & _end; sps = (caddr_t) spu_extract (sp_r1, 0); if (((int) sps - STACKSIZE - (int) heap_ptr) >= increment) { base = heap_ptr; heap_ptr += increment; sp_delta = (vector unsigned int) spu_insert (increment, spu_splats (0), 1); /* Subtract sp_delta from the SP limit (word 1). */ sp_r1 = spu_sub (sp_r1, sp_delta); /* Fix-up backchain. */ sp_ptr = (vector unsigned int *) spu_extract (sp_r1, 0); do { sp_reg = *sp_ptr; *sp_ptr = (vector unsigned int) spu_sub (sp_reg, sp_delta); } while ((sp_ptr = (vector unsigned int *) spu_extract (sp_reg, 0))); return (base); } else { errno = ENOMEM; return ((void *) -1); } }
void InitBasisEtc() { // Use a fixed initial step size for now; 128m for lod 0. // This yields an fft tile size of 32 x 128m = 4096m for lod 0 // and maximum dimensions of 8192m x 8192m step = g_R2OCon.m_step; vf32 step_vec = (vf32){step, 0, step, 0}; // get inverse-step using float magic (since taking the reciprocal of a power of 2 yields a 1-bit error) qword q_step = si_from_float(step); qword q_magic = si_ilhu(0x7F00); inv_step = si_to_float(si_sf(q_step, q_magic)); // set clip window clip_min = g_WaterObject.m_origin; clip_max = g_WaterObject.m_origin + g_WaterObject.m_dimensions; // set origin at gridpoint below clip min f32 magic_float = 1.5f * 8388608.0f * step; vf32 magic_vf32 = (vf32){magic_float, 0, magic_float, 0}; origin_world = (clip_min + magic_vf32) - magic_vf32; // compute gridpoint above clip max vf32 max_corner = (clip_max + magic_vf32) - magic_vf32; max_corner += step_vec; // offset both corners by the necessary amount of padding origin_world -= step_vec * spu_splats(8.0f); max_corner += step_vec * spu_splats(8.0f); // set num cols & num rows vf32 dims = max_corner - origin_world; nc = (i32)(spu_extract(dims,0) * inv_step) + 1; nr = (i32)(spu_extract(dims,2) * inv_step) + 1; // record true nc, nr true_nc = nc - 16; true_nr = nr - 16; // alignment requirements (ooh, that's a bit strict) nc = (nc + 7) & -8; nr = (nr + 7) & -8; // deal with large grids if (nc > 80) { nc = 80; true_nc = 64; dims = spu_insert((nc-1)*step, dims, 0); } if (nr > 80) { nr = 80; true_nr = 64; dims = spu_insert((nr-1)*step, dims, 2); } max_corner = origin_world + dims; even_step = step; even_inv_step = inv_step; even_basis_col = (vf32){1.0f, 0.0f, 0.0f, 0.0f}; even_basis_row = (vf32){0.0f, 0.0f, 1.0f, 0.0f}; const f32 r = 0.707106781187f; odd_step = even_step * r; odd_inv_step= even_inv_step * r * 2.0f; odd_basis_col = (vf32){ r, 0.0f, r, 0.0f}; odd_basis_row = (vf32){-r, 0.0f, r, 0.0f}; basis_col = even_basis_col; basis_row = even_basis_row; dvc_world = spu_splats(step) * basis_col; dvr_world = spu_splats(step) * basis_row; // set base lod origin g_RenderData.m_origins[0] = origin_world; g_RenderData.m_cols_rows[0] = nc<<8 | nr; c0_amb = 0; r0_amb = 0; SetBasisEtc(0,0); }