Пример #1
0
/**
 * @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);
}
Пример #2
0
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;
}
Пример #3
0
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;
}