/** * @brief Writes on the screen a formated string. * * @param fmt Formated string. */ PUBLIC void kprintf(const char *fmt, ...) { int i; /* Loop index. */ va_list args; /* Variable arguments list. */ char buffer[KBUFFER_SIZE + 1]; /* Temporary buffer. */ const char *buffer_no_code; /* Temporary buffer for log level printing. */ /* Convert to raw string. */ va_start(args, fmt); i = kvsprintf(buffer, fmt, args); buffer[i++] = '\n'; va_end(args); /* Save on kernel log, skip code in case it's not correctly done and write on kout. */ klog_write(0, buffer, i); buffer_no_code = skip_code(buffer, &i); cdev_write(kout, buffer_no_code, i); }
uint BVH4::get_potential_intersections(const Ray &ray, float tmax, uint max_potential, size_t *ids, void *state) { // Algorithm is based on the BVH4 algorithm from the paper // "Stackless Multi-BVH Traversal for CPU, MIC and GPU Ray Tracing" // by Afra et al. // Get state uint64_t& node = static_cast<uint64_t *>(state)[0]; uint64_t& bit_stack = static_cast<uint64_t *>(state)[1]; // Check if it's an empty BVH or if we have the "finished" magic number if (nodes.size() == 0 || node == ~uint64_t(0)) return 0; // Get inverse ray direction and whether each ray component is negative const Vec3 d_inv_f = ray.get_d_inverse(); const auto d_sign = ray.get_d_sign(); // Load ray origin, inverse direction, and max_t into simd layouts for intersection testing const SIMD::float4 ray_o[3] = {ray.o[0], ray.o[1], ray.o[2]}; const SIMD::float4 d_inv[3] = {d_inv_f[0], d_inv_f[1], d_inv_f[2]}; const SIMD::float4 max_t { ray.max_t }; // Traverse the BVH uint32_t hits_so_far = 0; while (hits_so_far < max_potential) { while (!is_leaf(node)) { // Inner node #ifdef GLOBAL_STATS_TOP_LEVEL_BVH_NODE_TESTS Global::Stats::top_level_bvh_node_tests += 4; #endif // Test ray against children's bboxes SIMD::float4 near_hits; uint32_t ti; float alpha; // Get the time-interpolated bounding box const BBox4 b = calc_time_interp(time_samples(node), ray.time, &ti, &alpha) ? lerp(alpha, nodes[node+ti].bounds, nodes[node+ti+1].bounds) : nodes[node].bounds; // Ray test uint64_t hit_mask = b.intersect_ray(ray_o, d_inv, max_t, d_sign, &near_hits); // If we didn't hit anything, exit loop if (hit_mask == 0) break; bit_stack <<= 3; // Single hit switch (hit_mask) { case 1 << 0: node = child(node, 0); continue; case 1 << 1: node = child(node, 1); continue; case 1 << 2: node = child(node, 2); continue; case 1 << 3: node = child(node, 3); continue; } // Multiple hits // Find the index of the nearst hit int nearest_hit_i = 0; float nearest_hit = std::numeric_limits<float>::infinity(); for (int i = 0; i < 4; ++i) { if ((hit_mask & (1<<i)) && (near_hits[i] <= nearest_hit)) { nearest_hit = near_hits[i]; nearest_hit_i = i; } } // Add skip code to the bit stack and set the next node bit_stack |= skip_code(hit_mask, nearest_hit_i); node = child(node, nearest_hit_i); } if (is_leaf(node)) { // Leaf node ids[hits_so_far++] = node; } // If we've completed the full traversal if (bit_stack == 0) { node = ~uint64_t(0); // Magic number for "finished" break; } // Find the next node to work from while ((bit_stack & 7) == 0) { node = parent(node); bit_stack >>= 3; } // Traverse to the next available sibling node static const int code_table[8] = {0, 1, 2, 1, 3, 1, 2, 1}; const uint64_t code = bit_stack & 7; const uint64_t skip_code_next = code >> code_table[code]; node = next_sibling(node, code_table[code]); bit_stack = (bit_stack & ~7) | skip_code_next; } // Return the number of primitives accumulated return hits_so_far; }
static int cc_token(parser_ctx_t *ctx, void *lval) { unsigned id_len = 0; cc_var_t *var; static const WCHAR cc_onW[] = {'c','c','_','o','n',0}; static const WCHAR setW[] = {'s','e','t',0}; ctx->ptr++; if(!check_keyword(ctx, cc_onW, NULL)) return init_cc(ctx) ? 0 : -1; if(!check_keyword(ctx, setW, NULL)) { const WCHAR *ident; unsigned ident_len; cc_var_t *var; if(!init_cc(ctx)) return -1; if(!skip_spaces(ctx)) return lex_error(ctx, JS_E_EXPECTED_AT); if(!parse_cc_identifier(ctx, &ident, &ident_len)) return -1; if(!skip_spaces(ctx) || *ctx->ptr != '=') return lex_error(ctx, JS_E_EXPECTED_ASSIGN); ctx->ptr++; if(!parse_cc_expr(ctx)) { WARN("parsing CC expression failed\n"); return -1; } var = find_cc_var(ctx->script->cc, ident, ident_len); if(var) { var->val = ctx->ccval; }else { if(!new_cc_var(ctx->script->cc, ident, ident_len, ctx->ccval)) return lex_error(ctx, E_OUTOFMEMORY); } return 0; } if(!check_keyword(ctx, ifW, NULL)) { if(!init_cc(ctx)) return -1; if(!skip_spaces(ctx) || *ctx->ptr != '(') return lex_error(ctx, JS_E_MISSING_LBRACKET); if(!parse_cc_expr(ctx)) return -1; if(get_ccbool(ctx->ccval)) { /* continue parsing block inside if */ ctx->cc_if_depth++; return 0; } return skip_code(ctx, TRUE); } if(!check_keyword(ctx, elifW, NULL) || !check_keyword(ctx, elseW, NULL)) { if(!ctx->cc_if_depth) return lex_error(ctx, JS_E_SYNTAX); return skip_code(ctx, FALSE); } if(!check_keyword(ctx, endW, NULL)) { if(!ctx->cc_if_depth) return lex_error(ctx, JS_E_SYNTAX); ctx->cc_if_depth--; return 0; } if(!ctx->script->cc) return lex_error(ctx, JS_E_DISABLED_CC); while(ctx->ptr+id_len < ctx->end && is_identifier_char(ctx->ptr[id_len])) id_len++; if(!id_len) return '@'; TRACE("var %s\n", debugstr_wn(ctx->ptr, id_len)); var = find_cc_var(ctx->script->cc, ctx->ptr, id_len); ctx->ptr += id_len; if(!var || var->val.is_num) { *(literal_t**)lval = new_double_literal(ctx, var ? var->val.u.n : NAN); return tNumericLiteral; } *(literal_t**)lval = new_boolean_literal(ctx, var->val.u.b); return tBooleanLiteral; }