diff options
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/kernel/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/bvh/bvh.h | 98 | ||||
-rw-r--r-- | intern/cycles/kernel/bvh/bvh_shadow_all.h | 19 | ||||
-rw-r--r-- | intern/cycles/kernel/bvh/bvh_util.h | 162 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 17 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 2 | ||||
-rw-r--r-- | intern/cycles/render/shader.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/util/util_simd.h | 8 | ||||
-rw-r--r-- | intern/cycles/util/util_sseb.h | 12 | ||||
-rw-r--r-- | intern/cycles/util/util_ssef.h | 4 | ||||
-rw-r--r-- | intern/cycles/util/util_ssei.h | 13 | ||||
-rw-r--r-- | intern/cycles/util/util_system.cpp | 25 |
12 files changed, 229 insertions, 134 deletions
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index f6b4b963a7a..ea0f16c9233 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -93,6 +93,7 @@ set(SRC_BVH_HEADERS bvh/bvh_local.h bvh/bvh_traversal.h bvh/bvh_types.h + bvh/bvh_util.h bvh/bvh_volume.h bvh/bvh_volume_all.h bvh/bvh_embree.h diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h index 3049f243ae9..3a3f38539c5 100644 --- a/intern/cycles/kernel/bvh/bvh.h +++ b/intern/cycles/kernel/bvh/bvh.h @@ -29,9 +29,10 @@ # include "kernel/bvh/bvh_embree.h" #endif -CCL_NAMESPACE_BEGIN - #include "kernel/bvh/bvh_types.h" +#include "kernel/bvh/bvh_util.h" + +CCL_NAMESPACE_BEGIN #ifndef __KERNEL_OPTIX__ @@ -533,97 +534,4 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg, } #endif /* __VOLUME_RECORD_ALL__ */ -/* Ray offset to avoid self intersection. - * - * This function should be used to compute a modified ray start position for - * rays leaving from a surface. */ - -ccl_device_inline float3 ray_offset(float3 P, float3 Ng) -{ -#ifdef __INTERSECTION_REFINE__ - const float epsilon_f = 1e-5f; - /* ideally this should match epsilon_f, but instancing and motion blur - * precision makes it problematic */ - const float epsilon_test = 1.0f; - const int epsilon_i = 32; - - float3 res; - - /* x component */ - if (fabsf(P.x) < epsilon_test) { - res.x = P.x + Ng.x * epsilon_f; - } - else { - uint ix = __float_as_uint(P.x); - ix += ((ix ^ __float_as_uint(Ng.x)) >> 31) ? -epsilon_i : epsilon_i; - res.x = __uint_as_float(ix); - } - - /* y component */ - if (fabsf(P.y) < epsilon_test) { - res.y = P.y + Ng.y * epsilon_f; - } - else { - uint iy = __float_as_uint(P.y); - iy += ((iy ^ __float_as_uint(Ng.y)) >> 31) ? -epsilon_i : epsilon_i; - res.y = __uint_as_float(iy); - } - - /* z component */ - if (fabsf(P.z) < epsilon_test) { - res.z = P.z + Ng.z * epsilon_f; - } - else { - uint iz = __float_as_uint(P.z); - iz += ((iz ^ __float_as_uint(Ng.z)) >> 31) ? -epsilon_i : epsilon_i; - res.z = __uint_as_float(iz); - } - - return res; -#else - const float epsilon_f = 1e-4f; - return P + epsilon_f * Ng; -#endif -} - -#if defined(__VOLUME_RECORD_ALL__) || (defined(__SHADOW_RECORD_ALL__) && defined(__KERNEL_CPU__)) -/* ToDo: Move to another file? */ -ccl_device int intersections_compare(const void *a, const void *b) -{ - const Intersection *isect_a = (const Intersection *)a; - const Intersection *isect_b = (const Intersection *)b; - - if (isect_a->t < isect_b->t) - return -1; - else if (isect_a->t > isect_b->t) - return 1; - else - return 0; -} -#endif - -#if defined(__SHADOW_RECORD_ALL__) -ccl_device_inline void sort_intersections(Intersection *hits, uint num_hits) -{ -# ifdef __KERNEL_GPU__ - /* Use bubble sort which has more friendly memory pattern on GPU. */ - bool swapped; - do { - swapped = false; - for (int j = 0; j < num_hits - 1; ++j) { - if (hits[j].t > hits[j + 1].t) { - struct Intersection tmp = hits[j]; - hits[j] = hits[j + 1]; - hits[j + 1] = tmp; - swapped = true; - } - } - --num_hits; - } while (swapped); -# else - qsort(hits, num_hits, sizeof(Intersection), intersections_compare); -# endif -} -#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */ - CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/bvh/bvh_shadow_all.h b/intern/cycles/kernel/bvh/bvh_shadow_all.h index dccd257d2de..2e94b1d7c37 100644 --- a/intern/cycles/kernel/bvh/bvh_shadow_all.h +++ b/intern/cycles/kernel/bvh/bvh_shadow_all.h @@ -180,25 +180,10 @@ ccl_device_inline /* todo: optimize so primitive visibility flag indicates if * the primitive has a transparent shadow shader? */ - int prim = kernel_tex_fetch(__prim_index, isect_array->prim); - int shader = 0; - -#ifdef __HAIR__ - if (kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE) -#endif - { - shader = kernel_tex_fetch(__tri_shader, prim); - } -#ifdef __HAIR__ - else { - float4 str = kernel_tex_fetch(__curves, prim); - shader = __float_as_int(str.z); - } -#endif - int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags; + const int flags = intersection_get_shader_flags(kg, isect_array); /* if no transparent shadows, all light is blocked */ - if (!(flag & SD_HAS_TRANSPARENT_SHADOW)) { + if (!(flags & SD_HAS_TRANSPARENT_SHADOW)) { return true; } /* if maximum number of hits reached, block all light */ diff --git a/intern/cycles/kernel/bvh/bvh_util.h b/intern/cycles/kernel/bvh/bvh_util.h new file mode 100644 index 00000000000..a694e4dc259 --- /dev/null +++ b/intern/cycles/kernel/bvh/bvh_util.h @@ -0,0 +1,162 @@ +/* + * Copyright 2011-2013 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +CCL_NAMESPACE_BEGIN + +/* Ray offset to avoid self intersection. + * + * This function should be used to compute a modified ray start position for + * rays leaving from a surface. */ + +ccl_device_inline float3 ray_offset(float3 P, float3 Ng) +{ +#ifdef __INTERSECTION_REFINE__ + const float epsilon_f = 1e-5f; + /* ideally this should match epsilon_f, but instancing and motion blur + * precision makes it problematic */ + const float epsilon_test = 1.0f; + const int epsilon_i = 32; + + float3 res; + + /* x component */ + if (fabsf(P.x) < epsilon_test) { + res.x = P.x + Ng.x * epsilon_f; + } + else { + uint ix = __float_as_uint(P.x); + ix += ((ix ^ __float_as_uint(Ng.x)) >> 31) ? -epsilon_i : epsilon_i; + res.x = __uint_as_float(ix); + } + + /* y component */ + if (fabsf(P.y) < epsilon_test) { + res.y = P.y + Ng.y * epsilon_f; + } + else { + uint iy = __float_as_uint(P.y); + iy += ((iy ^ __float_as_uint(Ng.y)) >> 31) ? -epsilon_i : epsilon_i; + res.y = __uint_as_float(iy); + } + + /* z component */ + if (fabsf(P.z) < epsilon_test) { + res.z = P.z + Ng.z * epsilon_f; + } + else { + uint iz = __float_as_uint(P.z); + iz += ((iz ^ __float_as_uint(Ng.z)) >> 31) ? -epsilon_i : epsilon_i; + res.z = __uint_as_float(iz); + } + + return res; +#else + const float epsilon_f = 1e-4f; + return P + epsilon_f * Ng; +#endif +} + +#if defined(__VOLUME_RECORD_ALL__) || (defined(__SHADOW_RECORD_ALL__) && defined(__KERNEL_CPU__)) +/* ToDo: Move to another file? */ +ccl_device int intersections_compare(const void *a, const void *b) +{ + const Intersection *isect_a = (const Intersection *)a; + const Intersection *isect_b = (const Intersection *)b; + + if (isect_a->t < isect_b->t) + return -1; + else if (isect_a->t > isect_b->t) + return 1; + else + return 0; +} +#endif + +#if defined(__SHADOW_RECORD_ALL__) +ccl_device_inline void sort_intersections(Intersection *hits, uint num_hits) +{ + kernel_assert(num_hits > 0); + +# ifdef __KERNEL_GPU__ + /* Use bubble sort which has more friendly memory pattern on GPU. */ + bool swapped; + do { + swapped = false; + for (int j = 0; j < num_hits - 1; ++j) { + if (hits[j].t > hits[j + 1].t) { + struct Intersection tmp = hits[j]; + hits[j] = hits[j + 1]; + hits[j + 1] = tmp; + swapped = true; + } + } + --num_hits; + } while (swapped); +# else + qsort(hits, num_hits, sizeof(Intersection), intersections_compare); +# endif +} +#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */ + +/* Utility to quickly get a shader flags from an intersection. */ + +ccl_device_forceinline int intersection_get_shader_flags(KernelGlobals *ccl_restrict kg, + const Intersection *isect) +{ + const int prim = kernel_tex_fetch(__prim_index, isect->prim); + int shader = 0; + +#ifdef __HAIR__ + if (kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) +#endif + { + shader = kernel_tex_fetch(__tri_shader, prim); + } +#ifdef __HAIR__ + else { + float4 str = kernel_tex_fetch(__curves, prim); + shader = __float_as_int(str.z); + } +#endif + + return kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags; +} + +ccl_device_forceinline int intersection_get_shader(KernelGlobals *ccl_restrict kg, + const Intersection *isect) +{ + const int prim = kernel_tex_fetch(__prim_index, isect->prim); + int shader = 0; + +#ifdef __HAIR__ + if (kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) +#endif + { + shader = kernel_tex_fetch(__tri_shader, prim); + } +#ifdef __HAIR__ + else { + float4 str = kernel_tex_fetch(__curves, prim); + shader = __float_as_int(str.z); + } +#endif + + return shader & SHADER_MASK; +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 5681510fc25..dd2390808ea 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -65,7 +65,6 @@ ccl_device_forceinline bool kernel_path_scene_intersect(KernelGlobals *kg, uint visibility = path_state_ray_visibility(kg, state); if (path_state_ao_bounce(kg, state)) { - visibility = PATH_RAY_SHADOW; ray->t = kernel_data.background.ao_distance; } @@ -416,7 +415,13 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, break; } else if (path_state_ao_bounce(kg, state)) { - break; + if (intersection_get_shader_flags(kg, &isect) & + (SD_HAS_TRANSPARENT_SHADOW | SD_HAS_EMISSION)) { + state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT; + } + else { + break; + } } /* Setup shader data. */ @@ -554,7 +559,13 @@ ccl_device_forceinline void kernel_path_integrate(KernelGlobals *kg, break; } else if (path_state_ao_bounce(kg, state)) { - break; + if (intersection_get_shader_flags(kg, &isect) & + (SD_HAS_TRANSPARENT_SHADOW | SD_HAS_EMISSION)) { + state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT; + } + else { + break; + } } /* Setup shader data. */ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index ab54fda14af..18c4d2f86ad 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -895,6 +895,8 @@ enum ShaderDataFlag { SD_HAS_CONSTANT_EMISSION = (1 << 27), /* Needs to access attributes for volume rendering */ SD_NEED_VOLUME_ATTRIBUTES = (1 << 28), + /* Shader has emission */ + SD_HAS_EMISSION = (1 << 29), SD_SHADER_FLAGS = (SD_USE_MIS | SD_HAS_TRANSPARENT_SHADOW | SD_HAS_VOLUME | SD_HAS_ONLY_VOLUME | SD_HETEROGENEOUS_VOLUME | SD_HAS_BSSRDF_BUMP | SD_VOLUME_EQUIANGULAR | diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 5ecbd92d96d..44a48cd2839 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -528,6 +528,8 @@ void ShaderManager::device_update_common(Device *device, if (shader->get_use_mis()) flag |= SD_USE_MIS; + if (shader->has_surface_emission) + flag |= SD_HAS_EMISSION; if (shader->has_surface_transparent && shader->get_use_transparent_shadow()) flag |= SD_HAS_TRANSPARENT_SHADOW; if (shader->has_volume) { diff --git a/intern/cycles/util/util_simd.h b/intern/cycles/util/util_simd.h index 718ec9266b1..8e8caa98a1b 100644 --- a/intern/cycles/util/util_simd.h +++ b/intern/cycles/util/util_simd.h @@ -124,7 +124,7 @@ static struct StepTy { template<class type, int i0, int i1, int i2, int i3> type shuffle_neon(const type &a) { if (i0 == i1 && i0 == i2 && i0 == i3) { - return vdupq_laneq_s32(a, i0); + return type(vdupq_laneq_s32(int32x4_t(a), i0)); } static const uint8_t tbl[16] = {(i0 * 4) + 0, (i0 * 4) + 1, @@ -143,7 +143,7 @@ template<class type, int i0, int i1, int i2, int i3> type shuffle_neon(const typ (i3 * 4) + 2, (i3 * 4) + 3}; - return vqtbl1q_s8(int8x16_t(a), *(int8x16_t *)tbl); + return type(vqtbl1q_s8(int8x16_t(a), *(uint8x16_t *)tbl)); } template<class type, int i0, int i1, int i2, int i3> @@ -167,7 +167,7 @@ type shuffle_neon(const type &a, const type &b) (i3 * 4) + 2, (i3 * 4) + 3}; - return vqtbl1q_s8(int8x16_t(b), *(int8x16_t *)tbl); + return type(vqtbl1q_s8(int8x16_t(b), *(uint8x16_t *)tbl)); } else { @@ -188,7 +188,7 @@ type shuffle_neon(const type &a, const type &b) (i3 * 4) + 2 + 16, (i3 * 4) + 3 + 16}; - return vqtbl2q_s8((int8x16x2_t){a, b}, *(int8x16_t *)tbl); + return type(vqtbl2q_s8((int8x16x2_t){int8x16_t(a), int8x16_t(b)}, *(uint8x16_t *)tbl)); } } #endif /* __KERNEL_NEON */ diff --git a/intern/cycles/util/util_sseb.h b/intern/cycles/util/util_sseb.h index 1488da46b09..4dbd5b8046e 100644 --- a/intern/cycles/util/util_sseb.h +++ b/intern/cycles/util/util_sseb.h @@ -283,7 +283,7 @@ __forceinline uint32_t popcnt(const sseb &a) { # if defined(__KERNEL_NEON__) const int32x4_t mask = {1, 1, 1, 1}; - int32x4_t t = vandq_s32(a.m128, mask); + int32x4_t t = vandq_s32(vreinterpretq_s32_m128(a.m128), mask); return vaddvq_s32(t); # else return _mm_popcnt_u32(_mm_movemask_ps(a)); @@ -299,7 +299,7 @@ __forceinline uint32_t popcnt(const sseb &a) __forceinline bool reduce_and(const sseb &a) { # if defined(__KERNEL_NEON__) - return vaddvq_s32(a.m128) == -4; + return vaddvq_s32(vreinterpretq_s32_m128(a.m128)) == -4; # else return _mm_movemask_ps(a) == 0xf; # endif @@ -307,7 +307,7 @@ __forceinline bool reduce_and(const sseb &a) __forceinline bool reduce_or(const sseb &a) { # if defined(__KERNEL_NEON__) - return vaddvq_s32(a.m128) != 0x0; + return vaddvq_s32(vreinterpretq_s32_m128(a.m128)) != 0x0; # else return _mm_movemask_ps(a) != 0x0; # endif @@ -315,7 +315,7 @@ __forceinline bool reduce_or(const sseb &a) __forceinline bool all(const sseb &b) { # if defined(__KERNEL_NEON__) - return vaddvq_s32(b.m128) == -4; + return vaddvq_s32(vreinterpretq_s32_m128(b.m128)) == -4; # else return _mm_movemask_ps(b) == 0xf; # endif @@ -323,7 +323,7 @@ __forceinline bool all(const sseb &b) __forceinline bool any(const sseb &b) { # if defined(__KERNEL_NEON__) - return vaddvq_s32(b.m128) != 0x0; + return vaddvq_s32(vreinterpretq_s32_m128(b.m128)) != 0x0; # else return _mm_movemask_ps(b) != 0x0; # endif @@ -331,7 +331,7 @@ __forceinline bool any(const sseb &b) __forceinline bool none(const sseb &b) { # if defined(__KERNEL_NEON__) - return vaddvq_s32(b.m128) == 0x0; + return vaddvq_s32(vreinterpretq_s32_m128(b.m128)) == 0x0; # else return _mm_movemask_ps(b) == 0x0; # endif diff --git a/intern/cycles/util/util_ssef.h b/intern/cycles/util/util_ssef.h index d039b50a7d2..0c81ed87553 100644 --- a/intern/cycles/util/util_ssef.h +++ b/intern/cycles/util/util_ssef.h @@ -596,7 +596,7 @@ template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const ssef shuffle(const ssef &b) { # ifdef __KERNEL_NEON__ - return shuffle_neon<ssef, i0, i1, i2, i3>(b.m128); + return shuffle_neon<float32x4_t, i0, i1, i2, i3>(b.m128); # else return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(i3, i2, i1, i0))); # endif @@ -625,7 +625,7 @@ __forceinline const ssef shuffle(const ssef &a, const ssef &b) template<size_t i0> __forceinline const ssef shuffle(const ssef &a, const ssef &b) { # ifdef __KERNEL_NEON__ - return shuffle<float32x4_t, i0, i0, i0, i0>(a, b); + return shuffle_neon<float32x4_t, i0, i0, i0, i0>(a, b); # else return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i0, i0, i0, i0)); # endif diff --git a/intern/cycles/util/util_ssei.h b/intern/cycles/util/util_ssei.h index 3ec69ab3700..cd51dbff2f1 100644 --- a/intern/cycles/util/util_ssei.h +++ b/intern/cycles/util/util_ssei.h @@ -446,7 +446,8 @@ template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const ssei shuffle(const ssei &a) { # ifdef __KERNEL_NEON__ - return shuffle_neon<ssei, i0, i1, i2, i3>(a); + int32x4_t result = shuffle_neon<int32x4_t, i0, i1, i2, i3>(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(result); # else return _mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0)); # endif @@ -456,7 +457,9 @@ template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const ssei shuffle(const ssei &a, const ssei &b) { # ifdef __KERNEL_NEON__ - return shuffle_neon<ssei, i0, i1, i2, i3>(a, b); + int32x4_t result = shuffle_neon<int32x4_t, i0, i1, i2, i3>(vreinterpretq_s32_m128i(a), + vreinterpretq_s32_m128i(b)); + return vreinterpretq_m128i_s32(result); # else return _mm_castps_si128( _mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0))); @@ -514,7 +517,7 @@ __forceinline const ssei vreduce_add(const ssei &v) __forceinline int reduce_min(const ssei &v) { # ifdef __KERNEL_NEON__ - return vminvq_s32(v); + return vminvq_s32(vreinterpretq_s32_m128i(v)); # else return extract<0>(vreduce_min(v)); # endif @@ -522,7 +525,7 @@ __forceinline int reduce_min(const ssei &v) __forceinline int reduce_max(const ssei &v) { # ifdef __KERNEL_NEON__ - return vmaxvq_s32(v); + return vmaxvq_s32(vreinterpretq_s32_m128i(v)); # else return extract<0>(vreduce_max(v)); # endif @@ -530,7 +533,7 @@ __forceinline int reduce_max(const ssei &v) __forceinline int reduce_add(const ssei &v) { # ifdef __KERNEL_NEON__ - return vaddvq_s32(v); + return vaddvq_s32(vreinterpretq_s32_m128i(v)); # else return extract<0>(vreduce_add(v)); # endif diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp index 2c1716ce515..6500a59e42c 100644 --- a/intern/cycles/util/util_system.cpp +++ b/intern/cycles/util/util_system.cpp @@ -166,12 +166,33 @@ static void __cpuid(int data[4], int selector) string system_cpu_brand_string() { +#if !defined(WIN32) && !defined(__x86_64__) && !defined(__i386__) + FILE *cpuinfo = fopen("/proc/cpuinfo", "r"); + if (cpuinfo != nullptr) { + char cpuinfo_buf[513] = ""; + fread(cpuinfo_buf, sizeof(cpuinfo_buf) - 1, 1, cpuinfo); + fclose(cpuinfo); + + char *modelname = strstr(cpuinfo_buf, "model name"); + if (modelname != nullptr) { + modelname = strchr(modelname, ':'); + if (modelname != nullptr) { + modelname += 2; + char *modelname_end = strchr(modelname, '\n'); + if (modelname_end != nullptr) { + *modelname_end = '\0'; + return modelname; + } + } + } + } +#else char buf[49] = {0}; int result[4] = {0}; __cpuid(result, 0x80000000); - if (result[0] >= (int)0x80000004) { + if (result[0] != 0 && result[0] >= (int)0x80000004) { __cpuid((int *)(buf + 0), 0x80000002); __cpuid((int *)(buf + 16), 0x80000003); __cpuid((int *)(buf + 32), 0x80000004); @@ -183,7 +204,7 @@ string system_cpu_brand_string() return brand; } - +#endif return "Unknown CPU"; } |