<commit_before>/* Copyright (c) 2017-2020 Hans-Kristian Arntzen
 *
 * 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.
 */

#pragma once

#include "vulkan_headers.hpp"
#include "texture_format.hpp"

namespace Vulkan
{
static inline bool format_is_srgb(VkFormat format)
{
	switch (format)
	{
	case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
	case VK_FORMAT_R8G8B8A8_SRGB:
	case VK_FORMAT_B8G8R8A8_SRGB:
	case VK_FORMAT_R8_SRGB:
	case VK_FORMAT_R8G8_SRGB:
	case VK_FORMAT_R8G8B8_SRGB:
	case VK_FORMAT_B8G8R8_SRGB:
		return true;

	default:
		return false;
	}
}

static inline bool format_has_depth_aspect(VkFormat format)
{
	switch (format)
	{
	case VK_FORMAT_D16_UNORM:
	case VK_FORMAT_D16_UNORM_S8_UINT:
	case VK_FORMAT_D24_UNORM_S8_UINT:
	case VK_FORMAT_D32_SFLOAT:
	case VK_FORMAT_X8_D24_UNORM_PACK32:
	case VK_FORMAT_D32_SFLOAT_S8_UINT:
		return true;

	default:
		return false;
	}
}

static inline bool format_has_stencil_aspect(VkFormat format)
{
	switch (format)
	{
	case VK_FORMAT_D16_UNORM_S8_UINT:
	case VK_FORMAT_D24_UNORM_S8_UINT:
	case VK_FORMAT_D32_SFLOAT_S8_UINT:
	case VK_FORMAT_S8_UINT:
		return true;

	default:
		return false;
	}
}

static inline bool format_has_depth_or_stencil_aspect(VkFormat format)
{
	return format_has_depth_aspect(format) || format_has_stencil_aspect(format);
}

static inline VkImageAspectFlags format_to_aspect_mask(VkFormat format)
{
	switch (format)
	{
	case VK_FORMAT_UNDEFINED:
		return 0;

	case VK_FORMAT_S8_UINT:
		return VK_IMAGE_ASPECT_STENCIL_BIT;

	case VK_FORMAT_D16_UNORM_S8_UINT:
	case VK_FORMAT_D24_UNORM_S8_UINT:
	case VK_FORMAT_D32_SFLOAT_S8_UINT:
		return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;

	case VK_FORMAT_D16_UNORM:
	case VK_FORMAT_D32_SFLOAT:
	case VK_FORMAT_X8_D24_UNORM_PACK32:
		return VK_IMAGE_ASPECT_DEPTH_BIT;

	default:
		return VK_IMAGE_ASPECT_COLOR_BIT;
	}
}

static inline void format_align_dim(VkFormat format, uint32_t &width, uint32_t &height)
{
	uint32_t align_width, align_height;
	TextureFormatLayout::format_block_dim(format, align_width, align_height);
	width = ((width + align_width - 1) / align_width) * align_width;
	height = ((height + align_height - 1) / align_height) * align_height;
}

static inline void format_num_blocks(VkFormat format, uint32_t &width, uint32_t &height)
{
	uint32_t align_width, align_height;
	TextureFormatLayout::format_block_dim(format, align_width, align_height);
	width = (width + align_width - 1) / align_width;
	height = (height + align_height - 1) / align_height;
}

static inline VkDeviceSize format_get_layer_size(VkFormat format, VkImageAspectFlags aspect, unsigned width, unsigned height, unsigned depth)
{
	uint32_t blocks_x = width;
	uint32_t blocks_y = height;
	format_num_blocks(format, blocks_x, blocks_y);
	format_align_dim(format, width, height);

	VkDeviceSize size = TextureFormatLayout::format_block_size(format, aspect) * depth * blocks_x * blocks_y;
	return size;
}

enum class YCbCrFormat
{
	YUV420P_3PLANE,
	YUV444P_3PLANE,
	YUV422P_3PLANE,
	Count
};

static inline unsigned format_ycbcr_num_planes(VkFormat format)
{
	switch (format)
	{
	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
	case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
	case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
	case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
	case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
	case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
	case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
	case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
	case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
	case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
	case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
	case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
		return 3;

	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
	case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
	case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
	case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
	case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
	case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
		return 2;

	default:
		return 1;
	}
}

static inline unsigned format_ycbcr_num_planes(YCbCrFormat format)
{
	switch (format)
	{
	case YCbCrFormat::YUV420P_3PLANE:
	case YCbCrFormat::YUV422P_3PLANE:
	case YCbCrFormat::YUV444P_3PLANE:
		return 3;

	default:
		return 0;
	}
}

static inline void format_ycbcr_downsample_dimensions(VkFormat format, VkImageAspectFlags aspect, uint32_t &width, uint32_t &height)
{
	if (aspect == VK_IMAGE_ASPECT_PLANE_0_BIT)
		return;

	switch (format)
	{
#define fmt(x, sub0, sub1) \
	case VK_FORMAT_##x: \
		width >>= sub0; \
		height >>= sub1; \
		break

		fmt(G8_B8_R8_3PLANE_420_UNORM, 1, 1);
		fmt(G8_B8R8_2PLANE_420_UNORM, 1, 1);
		fmt(G8_B8_R8_3PLANE_422_UNORM, 1, 0);
		fmt(G8_B8R8_2PLANE_422_UNORM, 1, 0);
		fmt(G8_B8_R8_3PLANE_444_UNORM, 0, 0);

		fmt(G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, 1, 1);
		fmt(G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16, 1, 0);
		fmt(G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, 0, 0);
		fmt(G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, 1, 1);
		fmt(G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, 1, 0);

		fmt(G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16, 1, 1);
		fmt(G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16, 1, 0);
		fmt(G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16, 0, 0);
		fmt(G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, 1, 1);
		fmt(G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, 1, 0);

		fmt(G16_B16_R16_3PLANE_420_UNORM, 1, 1);
		fmt(G16_B16_R16_3PLANE_422_UNORM, 1, 0);
		fmt(G16_B16_R16_3PLANE_444_UNORM, 0, 0);
		fmt(G16_B16R16_2PLANE_420_UNORM, 1, 1);
		fmt(G16_B16R16_2PLANE_422_UNORM, 1, 0);

	default:
		break;
	}
#undef fmt
}

static inline unsigned format_ycbcr_downsample_ratio_log2(YCbCrFormat format, unsigned dim, unsigned plane)
{
	switch (format)
	{
	case YCbCrFormat::YUV420P_3PLANE:
		return plane > 0 ? 1 : 0;
	case YCbCrFormat::YUV422P_3PLANE:
		return plane > 0 && dim == 0 ? 1 : 0;

	default:
		return 0;
	}
}

static inline VkFormat format_ycbcr_plane_vk_format(YCbCrFormat format, unsigned plane)
{
	switch (format)
	{
	case YCbCrFormat::YUV420P_3PLANE:
		return VK_FORMAT_R8_UNORM;
	case YCbCrFormat::YUV422P_3PLANE:
		return plane > 0 ? VK_FORMAT_R8G8_UNORM : VK_FORMAT_R8_UNORM;
	case YCbCrFormat::YUV444P_3PLANE:
		return VK_FORMAT_R8_UNORM;

	default:
		return VK_FORMAT_UNDEFINED;
	}
}

static inline VkFormat format_ycbcr_planar_vk_format(YCbCrFormat format)
{
	switch (format)
	{
	case YCbCrFormat::YUV420P_3PLANE:
		return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
	case YCbCrFormat::YUV422P_3PLANE:
		return VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM;
	case YCbCrFormat::YUV444P_3PLANE:
		return VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM;

	default:
		return VK_FORMAT_UNDEFINED;
	}
}

}
<commit_msg>Add compressed sRGB formats to sRGB query helper.<commit_after>/* Copyright (c) 2017-2020 Hans-Kristian Arntzen
 *
 * 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.
 */

#pragma once

#include "vulkan_headers.hpp"
#include "texture_format.hpp"

namespace Vulkan
{
static inline bool format_is_srgb(VkFormat format)
{
	switch (format)
	{
	case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
	case VK_FORMAT_R8G8B8A8_SRGB:
	case VK_FORMAT_B8G8R8A8_SRGB:
	case VK_FORMAT_R8_SRGB:
	case VK_FORMAT_R8G8_SRGB:
	case VK_FORMAT_R8G8B8_SRGB:
	case VK_FORMAT_B8G8R8_SRGB:
	case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
	case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
	case VK_FORMAT_BC2_SRGB_BLOCK:
	case VK_FORMAT_BC3_SRGB_BLOCK:
	case VK_FORMAT_BC7_SRGB_BLOCK:
	case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
	case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
	case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
	case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
	case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
	case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
	case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
	case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
	case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
	case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
	case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
	case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
	case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
	case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
	case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
	case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
	case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
		return true;

	default:
		return false;
	}
}

static inline bool format_has_depth_aspect(VkFormat format)
{
	switch (format)
	{
	case VK_FORMAT_D16_UNORM:
	case VK_FORMAT_D16_UNORM_S8_UINT:
	case VK_FORMAT_D24_UNORM_S8_UINT:
	case VK_FORMAT_D32_SFLOAT:
	case VK_FORMAT_X8_D24_UNORM_PACK32:
	case VK_FORMAT_D32_SFLOAT_S8_UINT:
		return true;

	default:
		return false;
	}
}

static inline bool format_has_stencil_aspect(VkFormat format)
{
	switch (format)
	{
	case VK_FORMAT_D16_UNORM_S8_UINT:
	case VK_FORMAT_D24_UNORM_S8_UINT:
	case VK_FORMAT_D32_SFLOAT_S8_UINT:
	case VK_FORMAT_S8_UINT:
		return true;

	default:
		return false;
	}
}

static inline bool format_has_depth_or_stencil_aspect(VkFormat format)
{
	return format_has_depth_aspect(format) || format_has_stencil_aspect(format);
}

static inline VkImageAspectFlags format_to_aspect_mask(VkFormat format)
{
	switch (format)
	{
	case VK_FORMAT_UNDEFINED:
		return 0;

	case VK_FORMAT_S8_UINT:
		return VK_IMAGE_ASPECT_STENCIL_BIT;

	case VK_FORMAT_D16_UNORM_S8_UINT:
	case VK_FORMAT_D24_UNORM_S8_UINT:
	case VK_FORMAT_D32_SFLOAT_S8_UINT:
		return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;

	case VK_FORMAT_D16_UNORM:
	case VK_FORMAT_D32_SFLOAT:
	case VK_FORMAT_X8_D24_UNORM_PACK32:
		return VK_IMAGE_ASPECT_DEPTH_BIT;

	default:
		return VK_IMAGE_ASPECT_COLOR_BIT;
	}
}

static inline void format_align_dim(VkFormat format, uint32_t &width, uint32_t &height)
{
	uint32_t align_width, align_height;
	TextureFormatLayout::format_block_dim(format, align_width, align_height);
	width = ((width + align_width - 1) / align_width) * align_width;
	height = ((height + align_height - 1) / align_height) * align_height;
}

static inline void format_num_blocks(VkFormat format, uint32_t &width, uint32_t &height)
{
	uint32_t align_width, align_height;
	TextureFormatLayout::format_block_dim(format, align_width, align_height);
	width = (width + align_width - 1) / align_width;
	height = (height + align_height - 1) / align_height;
}

static inline VkDeviceSize format_get_layer_size(VkFormat format, VkImageAspectFlags aspect, unsigned width, unsigned height, unsigned depth)
{
	uint32_t blocks_x = width;
	uint32_t blocks_y = height;
	format_num_blocks(format, blocks_x, blocks_y);
	format_align_dim(format, width, height);

	VkDeviceSize size = TextureFormatLayout::format_block_size(format, aspect) * depth * blocks_x * blocks_y;
	return size;
}

enum class YCbCrFormat
{
	YUV420P_3PLANE,
	YUV444P_3PLANE,
	YUV422P_3PLANE,
	Count
};

static inline unsigned format_ycbcr_num_planes(VkFormat format)
{
	switch (format)
	{
	case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
	case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
	case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
	case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
	case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
	case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
	case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
	case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
	case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
	case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
	case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
	case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
		return 3;

	case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
	case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
	case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
	case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
	case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
	case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
	case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
		return 2;

	default:
		return 1;
	}
}

static inline unsigned format_ycbcr_num_planes(YCbCrFormat format)
{
	switch (format)
	{
	case YCbCrFormat::YUV420P_3PLANE:
	case YCbCrFormat::YUV422P_3PLANE:
	case YCbCrFormat::YUV444P_3PLANE:
		return 3;

	default:
		return 0;
	}
}

static inline void format_ycbcr_downsample_dimensions(VkFormat format, VkImageAspectFlags aspect, uint32_t &width, uint32_t &height)
{
	if (aspect == VK_IMAGE_ASPECT_PLANE_0_BIT)
		return;

	switch (format)
	{
#define fmt(x, sub0, sub1) \
	case VK_FORMAT_##x: \
		width >>= sub0; \
		height >>= sub1; \
		break

		fmt(G8_B8_R8_3PLANE_420_UNORM, 1, 1);
		fmt(G8_B8R8_2PLANE_420_UNORM, 1, 1);
		fmt(G8_B8_R8_3PLANE_422_UNORM, 1, 0);
		fmt(G8_B8R8_2PLANE_422_UNORM, 1, 0);
		fmt(G8_B8_R8_3PLANE_444_UNORM, 0, 0);

		fmt(G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, 1, 1);
		fmt(G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16, 1, 0);
		fmt(G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, 0, 0);
		fmt(G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, 1, 1);
		fmt(G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, 1, 0);

		fmt(G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16, 1, 1);
		fmt(G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16, 1, 0);
		fmt(G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16, 0, 0);
		fmt(G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, 1, 1);
		fmt(G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, 1, 0);

		fmt(G16_B16_R16_3PLANE_420_UNORM, 1, 1);
		fmt(G16_B16_R16_3PLANE_422_UNORM, 1, 0);
		fmt(G16_B16_R16_3PLANE_444_UNORM, 0, 0);
		fmt(G16_B16R16_2PLANE_420_UNORM, 1, 1);
		fmt(G16_B16R16_2PLANE_422_UNORM, 1, 0);

	default:
		break;
	}
#undef fmt
}

static inline unsigned format_ycbcr_downsample_ratio_log2(YCbCrFormat format, unsigned dim, unsigned plane)
{
	switch (format)
	{
	case YCbCrFormat::YUV420P_3PLANE:
		return plane > 0 ? 1 : 0;
	case YCbCrFormat::YUV422P_3PLANE:
		return plane > 0 && dim == 0 ? 1 : 0;

	default:
		return 0;
	}
}

static inline VkFormat format_ycbcr_plane_vk_format(YCbCrFormat format, unsigned plane)
{
	switch (format)
	{
	case YCbCrFormat::YUV420P_3PLANE:
		return VK_FORMAT_R8_UNORM;
	case YCbCrFormat::YUV422P_3PLANE:
		return plane > 0 ? VK_FORMAT_R8G8_UNORM : VK_FORMAT_R8_UNORM;
	case YCbCrFormat::YUV444P_3PLANE:
		return VK_FORMAT_R8_UNORM;

	default:
		return VK_FORMAT_UNDEFINED;
	}
}

static inline VkFormat format_ycbcr_planar_vk_format(YCbCrFormat format)
{
	switch (format)
	{
	case YCbCrFormat::YUV420P_3PLANE:
		return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
	case YCbCrFormat::YUV422P_3PLANE:
		return VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM;
	case YCbCrFormat::YUV444P_3PLANE:
		return VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM;

	default:
		return VK_FORMAT_UNDEFINED;
	}
}

}
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2012 Torus Knot Software Ltd
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.
-----------------------------------------------------------------------------
*/
#include "OgreShaderExTriplanarTexturing.h"
#ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS
#include "OgreShaderFFPRenderState.h"
#include "OgreShaderProgram.h"
#include "OgreShaderParameter.h"
#include "OgreShaderProgramSet.h"

namespace Ogre {
namespace RTShader {

    String TriplanarTexturing::type = "SGX_TriplanarTexturing";

    //-----------------------------------------------------------------------

    bool TriplanarTexturing::resolveParameters(ProgramSet* programSet)
    {
        Program* vsProgram = programSet->getCpuVertexProgram();
        Program* psProgram = programSet->getCpuFragmentProgram();
        Function* vsMain   = vsProgram->getEntryPointFunction();
        Function* psMain   = psProgram->getEntryPointFunction();

        // Resolve pixel shader output diffuse color.
        mPSInDiffuse = vsMain->resolveInputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4);

        // Resolve input vertex shader normal.
        mVSInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3);

        // Resolve output vertex shader normal.
        mVSOutNormal = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_NORMAL_VIEW_SPACE, GCT_FLOAT3);

        // Resolve input pixel shader normal.
        mPSInNormal = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES,
            mVSOutNormal->getIndex(),
            mVSOutNormal->getContent(),
            GCT_FLOAT3);

        // Resolve input vertex shader normal.
        mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4);

        mVSInPosition  = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4);
        mVSOutPosition = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4);
        mPSInPosition = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES,
            mVSOutPosition->getIndex(),
            mVSOutPosition->getContent(),
            GCT_FLOAT4);

        mSamplerFromX = psProgram->resolveParameter(GCT_SAMPLER2D, mTextureSamplerIndexFromX, (uint16)GPV_GLOBAL, "tp_sampler_from_x");
        if (mSamplerFromX.get() == NULL)
            return false;
        mSamplerFromY = psProgram->resolveParameter(GCT_SAMPLER2D, mTextureSamplerIndexFromY, (uint16)GPV_GLOBAL, "tp_sampler_from_y");
        if (mSamplerFromY.get() == NULL)
            return false;
        mSamplerFromZ = psProgram->resolveParameter(GCT_SAMPLER2D, mTextureSamplerIndexFromZ, (uint16)GPV_GLOBAL, "tp_sampler_from_z");
        if (mSamplerFromZ.get() == NULL)
            return false;

        mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4);
        if (mPSOutDiffuse.get() == NULL)
            return false;

        mPSTPParams = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_GLOBAL, "gTPParams");
        if (mPSTPParams.get() == NULL)
            return false;
        return true;
    }

    //-----------------------------------------------------------------------
    bool TriplanarTexturing::resolveDependencies(ProgramSet* programSet)
    {
        Program* psProgram = programSet->getCpuFragmentProgram();
        Program* vsProgram = programSet->getCpuVertexProgram();
        psProgram->addDependency("SGXLib_TriplanarTexturing");
        vsProgram->addDependency(FFP_LIB_COMMON);
        return true;
    }

    //-----------------------------------------------------------------------
    bool TriplanarTexturing::addFunctionInvocations(ProgramSet* programSet)
    {
        Program* psProgram = programSet->getCpuFragmentProgram();
        Function* psMain = psProgram->getEntryPointFunction();
        Program* vsProgram = programSet->getCpuVertexProgram();
        Function* vsMain = vsProgram->getEntryPointFunction();

        size_t internalCounter = 0;

        FunctionInvocation *curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, internalCounter++);
        curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mVSOutNormal, Operand::OPS_OUT);
        vsMain->addAtomInstance(curFuncInvocation);

        curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, internalCounter++);
        curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mVSOutPosition, Operand::OPS_OUT);
        vsMain->addAtomInstance(curFuncInvocation);

        curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRIPLANAR_TEXTURING, FFP_PS_TEXTURING, internalCounter++);
        curFuncInvocation->pushOperand(mPSInDiffuse, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mPSInPosition, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mSamplerFromX, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mSamplerFromY, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mSamplerFromZ, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mPSTPParams, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT);
        psMain->addAtomInstance(curFuncInvocation);

        return true;
    }

    //-----------------------------------------------------------------------
    const String& TriplanarTexturing::getType() const
    {
        return type;
    }

    //-----------------------------------------------------------------------
    int	TriplanarTexturing::getExecutionOrder() const
    {
        return FFP_TEXTURING;
    }

    //-----------------------------------------------------------------------
    bool TriplanarTexturing::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass )
    {
        TextureUnitState* textureUnit;

        // Create the mapping textures
        textureUnit = dstPass->createTextureUnitState();
        textureUnit->setTextureName(mTextureNameFromX);
        mTextureSamplerIndexFromX = dstPass->getNumTextureUnitStates() - 1;

        textureUnit = dstPass->createTextureUnitState();
        textureUnit->setTextureName(mTextureNameFromY);
        mTextureSamplerIndexFromY = dstPass->getNumTextureUnitStates() - 1;

        textureUnit = dstPass->createTextureUnitState();
        textureUnit->setTextureName(mTextureNameFromZ);
        mTextureSamplerIndexFromZ = dstPass->getNumTextureUnitStates() - 1;
        return true;
    }

    //-----------------------------------------------------------------------
    void TriplanarTexturing::copyFrom(const SubRenderState& rhs)
    {
        const TriplanarTexturing& rhsTP = static_cast<const TriplanarTexturing&>(rhs);
        mPSOutDiffuse = rhsTP.mPSOutDiffuse;
        mPSInDiffuse = rhsTP.mPSInDiffuse;

        mVSInPosition = rhsTP.mVSInPosition;
        mVSOutPosition = rhsTP.mVSOutPosition;

        mVSOutNormal = rhsTP.mVSOutNormal;
        mVSInNormal = rhsTP.mVSInNormal;
        mPSInNormal = rhsTP.mPSInNormal;

        mVSOutPosition = rhsTP.mVSOutPosition;
        mVSInPosition = rhsTP.mVSInPosition;
        mPSInPosition = rhsTP.mPSInPosition;

        mSamplerFromX = rhsTP.mSamplerFromX;
        mSamplerFromY = rhsTP.mSamplerFromY;
        mSamplerFromZ = rhsTP.mSamplerFromZ;

        mPSTPParams = rhsTP.mPSTPParams;
        mParameters = rhsTP.mParameters;

        mTextureNameFromX = rhsTP.mTextureNameFromX;
        mTextureNameFromY = rhsTP.mTextureNameFromY;
        mTextureNameFromZ = rhsTP.mTextureNameFromZ;
    }

    //-----------------------------------------------------------------------
    void TriplanarTexturing::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source,
                                         const LightList* pLightList)
    {
        mPSTPParams->setGpuParameter(mParameters);
    }

    //-----------------------------------------------------------------------
    void TriplanarTexturing::setParameters(const Vector3 &parameters)
    {
        mParameters = parameters;
    }

    //-----------------------------------------------------------------------
    void TriplanarTexturing::setTextureNames(const String &textureNameFromX, const String &textureNameFromY, const String &textureNameFromZ)
    {
        mTextureNameFromX = textureNameFromX;
        mTextureNameFromY = textureNameFromY;
        mTextureNameFromZ = textureNameFromZ;
    }

    //-----------------------------------------------------------------------
    const String& TriplanarTexturingFactory::getType() const
    {
        return TriplanarTexturing::type;
    }

    //-----------------------------------------------------------------------
    SubRenderState*	TriplanarTexturingFactory::createInstance(ScriptCompiler* compiler,
                                                       PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator)
    {

        if (prop->name == "triplanarTexturing")
        {
            if (prop->values.size() == 6)
            {
                SubRenderState* subRenderState = createOrRetrieveInstance(translator);
                TriplanarTexturing* tpSubRenderState = static_cast<TriplanarTexturing*>(subRenderState);
                float parameters[3];
                ColourValue cValue;
                AbstractNodeList::const_iterator it = prop->values.begin();
                if (false == SGScriptTranslator::getFloat(*it, parameters))
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    return NULL;
                }
                it++;
                if (false == SGScriptTranslator::getFloat(*it, parameters + 1))
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    return NULL;
                }
                it++;
                if (false == SGScriptTranslator::getFloat(*it, parameters + 2))
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    return NULL;
                }
                Vector3 vParameters(parameters[0], parameters[1], parameters[2]);
                tpSubRenderState->setParameters(vParameters);

                String textureNameFromX, textureNameFromY, textureNameFromZ;
                it++;
                if (false == SGScriptTranslator::getString(*it, &textureNameFromX))
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    return NULL;
                }
                it++;
                if (false == SGScriptTranslator::getString(*it, &textureNameFromY))
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    return NULL;
                }
                it++;
                if (false == SGScriptTranslator::getString(*it, &textureNameFromZ))
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    return NULL;
                }
                tpSubRenderState->setTextureNames(textureNameFromX, textureNameFromY, textureNameFromZ);

                return subRenderState;
            }
            else
            {
                compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
            }
        }

        return NULL;
    }

    //-----------------------------------------------------------------------
    SubRenderState*	TriplanarTexturingFactory::createInstanceImpl()
    {
        return OGRE_NEW TriplanarTexturing;
    }

}
}

#endif
<commit_msg>RTSS: removed unused var<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2012 Torus Knot Software Ltd
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.
-----------------------------------------------------------------------------
*/
#include "OgreShaderExTriplanarTexturing.h"
#ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS
#include "OgreShaderFFPRenderState.h"
#include "OgreShaderProgram.h"
#include "OgreShaderParameter.h"
#include "OgreShaderProgramSet.h"

namespace Ogre {
namespace RTShader {

    String TriplanarTexturing::type = "SGX_TriplanarTexturing";

    //-----------------------------------------------------------------------

    bool TriplanarTexturing::resolveParameters(ProgramSet* programSet)
    {
        Program* vsProgram = programSet->getCpuVertexProgram();
        Program* psProgram = programSet->getCpuFragmentProgram();
        Function* vsMain   = vsProgram->getEntryPointFunction();
        Function* psMain   = psProgram->getEntryPointFunction();

        // Resolve pixel shader output diffuse color.
        mPSInDiffuse = vsMain->resolveInputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4);

        // Resolve input vertex shader normal.
        mVSInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3);

        // Resolve output vertex shader normal.
        mVSOutNormal = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_NORMAL_VIEW_SPACE, GCT_FLOAT3);

        // Resolve input pixel shader normal.
        mPSInNormal = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES,
            mVSOutNormal->getIndex(),
            mVSOutNormal->getContent(),
            GCT_FLOAT3);

        // Resolve input vertex shader normal.
        mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4);

        mVSInPosition  = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4);
        mVSOutPosition = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4);
        mPSInPosition = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES,
            mVSOutPosition->getIndex(),
            mVSOutPosition->getContent(),
            GCT_FLOAT4);

        mSamplerFromX = psProgram->resolveParameter(GCT_SAMPLER2D, mTextureSamplerIndexFromX, (uint16)GPV_GLOBAL, "tp_sampler_from_x");
        if (mSamplerFromX.get() == NULL)
            return false;
        mSamplerFromY = psProgram->resolveParameter(GCT_SAMPLER2D, mTextureSamplerIndexFromY, (uint16)GPV_GLOBAL, "tp_sampler_from_y");
        if (mSamplerFromY.get() == NULL)
            return false;
        mSamplerFromZ = psProgram->resolveParameter(GCT_SAMPLER2D, mTextureSamplerIndexFromZ, (uint16)GPV_GLOBAL, "tp_sampler_from_z");
        if (mSamplerFromZ.get() == NULL)
            return false;

        mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4);
        if (mPSOutDiffuse.get() == NULL)
            return false;

        mPSTPParams = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_GLOBAL, "gTPParams");
        if (mPSTPParams.get() == NULL)
            return false;
        return true;
    }

    //-----------------------------------------------------------------------
    bool TriplanarTexturing::resolveDependencies(ProgramSet* programSet)
    {
        Program* psProgram = programSet->getCpuFragmentProgram();
        Program* vsProgram = programSet->getCpuVertexProgram();
        psProgram->addDependency("SGXLib_TriplanarTexturing");
        vsProgram->addDependency(FFP_LIB_COMMON);
        return true;
    }

    //-----------------------------------------------------------------------
    bool TriplanarTexturing::addFunctionInvocations(ProgramSet* programSet)
    {
        Program* psProgram = programSet->getCpuFragmentProgram();
        Function* psMain = psProgram->getEntryPointFunction();
        Program* vsProgram = programSet->getCpuVertexProgram();
        Function* vsMain = vsProgram->getEntryPointFunction();

        size_t internalCounter = 0;

        FunctionInvocation *curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, internalCounter++);
        curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mVSOutNormal, Operand::OPS_OUT);
        vsMain->addAtomInstance(curFuncInvocation);

        curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, internalCounter++);
        curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mVSOutPosition, Operand::OPS_OUT);
        vsMain->addAtomInstance(curFuncInvocation);

        curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRIPLANAR_TEXTURING, FFP_PS_TEXTURING, internalCounter++);
        curFuncInvocation->pushOperand(mPSInDiffuse, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mPSInPosition, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mSamplerFromX, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mSamplerFromY, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mSamplerFromZ, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mPSTPParams, Operand::OPS_IN);
        curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT);
        psMain->addAtomInstance(curFuncInvocation);

        return true;
    }

    //-----------------------------------------------------------------------
    const String& TriplanarTexturing::getType() const
    {
        return type;
    }

    //-----------------------------------------------------------------------
    int	TriplanarTexturing::getExecutionOrder() const
    {
        return FFP_TEXTURING;
    }

    //-----------------------------------------------------------------------
    bool TriplanarTexturing::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass )
    {
        TextureUnitState* textureUnit;

        // Create the mapping textures
        textureUnit = dstPass->createTextureUnitState();
        textureUnit->setTextureName(mTextureNameFromX);
        mTextureSamplerIndexFromX = dstPass->getNumTextureUnitStates() - 1;

        textureUnit = dstPass->createTextureUnitState();
        textureUnit->setTextureName(mTextureNameFromY);
        mTextureSamplerIndexFromY = dstPass->getNumTextureUnitStates() - 1;

        textureUnit = dstPass->createTextureUnitState();
        textureUnit->setTextureName(mTextureNameFromZ);
        mTextureSamplerIndexFromZ = dstPass->getNumTextureUnitStates() - 1;
        return true;
    }

    //-----------------------------------------------------------------------
    void TriplanarTexturing::copyFrom(const SubRenderState& rhs)
    {
        const TriplanarTexturing& rhsTP = static_cast<const TriplanarTexturing&>(rhs);
        mPSOutDiffuse = rhsTP.mPSOutDiffuse;
        mPSInDiffuse = rhsTP.mPSInDiffuse;

        mVSInPosition = rhsTP.mVSInPosition;
        mVSOutPosition = rhsTP.mVSOutPosition;

        mVSOutNormal = rhsTP.mVSOutNormal;
        mVSInNormal = rhsTP.mVSInNormal;
        mPSInNormal = rhsTP.mPSInNormal;

        mVSOutPosition = rhsTP.mVSOutPosition;
        mVSInPosition = rhsTP.mVSInPosition;
        mPSInPosition = rhsTP.mPSInPosition;

        mSamplerFromX = rhsTP.mSamplerFromX;
        mSamplerFromY = rhsTP.mSamplerFromY;
        mSamplerFromZ = rhsTP.mSamplerFromZ;

        mPSTPParams = rhsTP.mPSTPParams;
        mParameters = rhsTP.mParameters;

        mTextureNameFromX = rhsTP.mTextureNameFromX;
        mTextureNameFromY = rhsTP.mTextureNameFromY;
        mTextureNameFromZ = rhsTP.mTextureNameFromZ;
    }

    //-----------------------------------------------------------------------
    void TriplanarTexturing::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source,
                                         const LightList* pLightList)
    {
        mPSTPParams->setGpuParameter(mParameters);
    }

    //-----------------------------------------------------------------------
    void TriplanarTexturing::setParameters(const Vector3 &parameters)
    {
        mParameters = parameters;
    }

    //-----------------------------------------------------------------------
    void TriplanarTexturing::setTextureNames(const String &textureNameFromX, const String &textureNameFromY, const String &textureNameFromZ)
    {
        mTextureNameFromX = textureNameFromX;
        mTextureNameFromY = textureNameFromY;
        mTextureNameFromZ = textureNameFromZ;
    }

    //-----------------------------------------------------------------------
    const String& TriplanarTexturingFactory::getType() const
    {
        return TriplanarTexturing::type;
    }

    //-----------------------------------------------------------------------
    SubRenderState*	TriplanarTexturingFactory::createInstance(ScriptCompiler* compiler,
                                                       PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator)
    {

        if (prop->name == "triplanarTexturing")
        {
            if (prop->values.size() == 6)
            {
                SubRenderState* subRenderState = createOrRetrieveInstance(translator);
                TriplanarTexturing* tpSubRenderState = static_cast<TriplanarTexturing*>(subRenderState);
                float parameters[3];
                AbstractNodeList::const_iterator it = prop->values.begin();
                if (false == SGScriptTranslator::getFloat(*it, parameters))
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    return NULL;
                }
                it++;
                if (false == SGScriptTranslator::getFloat(*it, parameters + 1))
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    return NULL;
                }
                it++;
                if (false == SGScriptTranslator::getFloat(*it, parameters + 2))
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    return NULL;
                }
                Vector3 vParameters(parameters[0], parameters[1], parameters[2]);
                tpSubRenderState->setParameters(vParameters);

                String textureNameFromX, textureNameFromY, textureNameFromZ;
                it++;
                if (false == SGScriptTranslator::getString(*it, &textureNameFromX))
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    return NULL;
                }
                it++;
                if (false == SGScriptTranslator::getString(*it, &textureNameFromY))
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    return NULL;
                }
                it++;
                if (false == SGScriptTranslator::getString(*it, &textureNameFromZ))
                {
                    compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
                    return NULL;
                }
                tpSubRenderState->setTextureNames(textureNameFromX, textureNameFromY, textureNameFromZ);

                return subRenderState;
            }
            else
            {
                compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line);
            }
        }

        return NULL;
    }

    //-----------------------------------------------------------------------
    SubRenderState*	TriplanarTexturingFactory::createInstanceImpl()
    {
        return OGRE_NEW TriplanarTexturing;
    }

}
}

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 *
 */

#include "ip.hh"
#include "core/print.hh"

namespace net {

std::ostream& operator<<(std::ostream& os, ipv4_address a) {
    auto ip = a.ip;
    return fprint(os, "%d.%d.%d.%d",
            (ip >> 24) & 0xff,
            (ip >> 16) & 0xff,
            (ip >> 8) & 0xff,
            (ip >> 0) & 0xff);
}

uint16_t ip_checksum(const void* data, size_t len) {
    uint64_t csum = 0;
    auto p64 = reinterpret_cast<const packed<uint64_t>*>(data);
    while (len >= 8) {
        auto old = csum;
        csum += ntohq(*p64++);
        csum += (csum < old);
        len -= 8;
    }
    auto p16 = reinterpret_cast<const packed<uint16_t>*>(p64);
    while (len >= 2) {
        auto old = csum;
        csum += ntohs(*p16++);
        csum += (csum < old);
        len -= 2;
    }
    auto p8 = reinterpret_cast<const uint8_t*>(p16);
    if (len) {
        auto old = csum;
        csum += *p8++ << 8;
        csum += (csum < old);
        len -= 1;
    }
    csum = (csum & 0xffff) + ((csum >> 16) & 0xffff) + ((csum >> 32) & 0xffff) + (csum >> 48);
    csum += csum >> 16;
    return htons(~csum);
}

ipv4::ipv4(interface* netif)
    : _netif(netif)
    , _global_arp(netif)
    , _arp(_global_arp)
    , _l3(netif, 0x0800)
    , _l4({}) {
    run();
}

bool ipv4::in_my_netmask(ipv4_address a) const {
    return !((a.ip ^ _host_address.ip) & _netmask.ip);
}

void ipv4::run() {
    _l3.receive().then([this] (packet p, ethernet_address from) {
        handle_received_packet(std::move(p), from);
        run();
    });
}

void ipv4::handle_received_packet(packet p, ethernet_address from) {
    auto iph = p.get_header<ip_hdr>(0);
    if (!iph) {
        return;
    }
    ntoh(*iph);
    // FIXME: process options
    if (in_my_netmask(iph->src_ip) && iph->src_ip != _host_address) {
        _arp.learn(from, iph->src_ip);
    }
    if (iph->frag & 0x3fff) {
        // FIXME: defragment
        return;
    }
    if (iph->dst_ip != _host_address) {
        // FIXME: forward
        return;
    }
    auto l4 = _l4[iph->ip_proto];
    if (l4) {
        p.trim_front(iph->ihl * 4);
        l4->received(std::move(p), iph->src_ip, iph->dst_ip);
    }
}

void ipv4::send(ipv4_address to, uint8_t proto_num, packet p) {
    // FIXME: fragment
    ip_hdr iph;
    iph.ihl = sizeof(iph) / 4;
    iph.ver = 4;
    iph.dscp = 0;
    iph.ecn = 0;
    iph.len = p.len;
    iph.id = 0;
    iph.frag = 0;
    iph.ttl = 64;
    iph.ip_proto = proto_num;
    iph.csum = 0;
    iph.src_ip = _host_address;
    // FIXME: routing
    auto gw = to;
    iph.dst_ip = to;
    checksummer csum;
    csum.sum(reinterpret_cast<char*>(&iph), sizeof(iph));
    csum.sum(p);
    auto q = packet(fragment{reinterpret_cast<char*>(&iph), sizeof(iph)}, std::move(p));
    _arp.lookup(gw).then([this, p = std::move(q)] (ethernet_address e_dst) mutable {
        _send_sem.wait().then([this, e_dst, p = std::move(p)] () mutable {
            return _l3.send(e_dst, std::move(p));
        }).then([this] {
            _send_sem.signal();
        });
    });
}

void ipv4::set_host_address(ipv4_address ip) {
    _host_address = ip;
    _arp.set_self_addr(ip);
}

void checksummer::sum(const char* data, size_t len) {
    auto orig_len = len;
    if (odd) {
        partial += uint8_t(*data++);
        --len;
    }
    partial += ip_checksum(data, len);
    odd ^= orig_len & 1;
}

void checksummer::sum(const packet& p) {
    for (auto&& f : p.fragments) {
        sum(f.base, f.size);
    }
}

uint16_t checksummer::get() const {
    return partial + (partial >> 16);
}

}
<commit_msg>net: fix ip tx<commit_after>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 *
 */

#include "ip.hh"
#include "core/print.hh"

namespace net {

std::ostream& operator<<(std::ostream& os, ipv4_address a) {
    auto ip = a.ip;
    return fprint(os, "%d.%d.%d.%d",
            (ip >> 24) & 0xff,
            (ip >> 16) & 0xff,
            (ip >> 8) & 0xff,
            (ip >> 0) & 0xff);
}

uint16_t ip_checksum(const void* data, size_t len) {
    uint64_t csum = 0;
    auto p64 = reinterpret_cast<const packed<uint64_t>*>(data);
    while (len >= 8) {
        auto old = csum;
        csum += ntohq(*p64++);
        csum += (csum < old);
        len -= 8;
    }
    auto p16 = reinterpret_cast<const packed<uint16_t>*>(p64);
    while (len >= 2) {
        auto old = csum;
        csum += ntohs(*p16++);
        csum += (csum < old);
        len -= 2;
    }
    auto p8 = reinterpret_cast<const uint8_t*>(p16);
    if (len) {
        auto old = csum;
        csum += *p8++ << 8;
        csum += (csum < old);
        len -= 1;
    }
    csum = (csum & 0xffff) + ((csum >> 16) & 0xffff) + ((csum >> 32) & 0xffff) + (csum >> 48);
    csum += csum >> 16;
    return htons(~csum);
}

ipv4::ipv4(interface* netif)
    : _netif(netif)
    , _global_arp(netif)
    , _arp(_global_arp)
    , _l3(netif, 0x0800)
    , _l4({}) {
    run();
}

bool ipv4::in_my_netmask(ipv4_address a) const {
    return !((a.ip ^ _host_address.ip) & _netmask.ip);
}

void ipv4::run() {
    _l3.receive().then([this] (packet p, ethernet_address from) {
        handle_received_packet(std::move(p), from);
        run();
    });
}

void ipv4::handle_received_packet(packet p, ethernet_address from) {
    auto iph = p.get_header<ip_hdr>(0);
    if (!iph) {
        return;
    }
    ntoh(*iph);
    // FIXME: process options
    if (in_my_netmask(iph->src_ip) && iph->src_ip != _host_address) {
        _arp.learn(from, iph->src_ip);
    }
    if (iph->frag & 0x3fff) {
        // FIXME: defragment
        return;
    }
    if (iph->dst_ip != _host_address) {
        // FIXME: forward
        return;
    }
    auto l4 = _l4[iph->ip_proto];
    if (l4) {
        p.trim_front(iph->ihl * 4);
        l4->received(std::move(p), iph->src_ip, iph->dst_ip);
    }
}

void ipv4::send(ipv4_address to, uint8_t proto_num, packet p) {
    // FIXME: fragment
    ip_hdr iph;
    iph.ihl = sizeof(iph) / 4;
    iph.ver = 4;
    iph.dscp = 0;
    iph.ecn = 0;
    iph.len = sizeof(iph) + p.len;
    iph.id = 0;
    iph.frag = 0;
    iph.ttl = 64;
    iph.ip_proto = proto_num;
    iph.csum = 0;
    iph.src_ip = _host_address;
    // FIXME: routing
    auto gw = to;
    iph.dst_ip = to;
    hton(iph);
    checksummer csum;
    csum.sum(reinterpret_cast<char*>(&iph), sizeof(iph));
    iph.csum = csum.get();
    auto q = packet(fragment{reinterpret_cast<char*>(&iph), sizeof(iph)}, std::move(p));
    _arp.lookup(gw).then([this, p = std::move(q)] (ethernet_address e_dst) mutable {
        _send_sem.wait().then([this, e_dst, p = std::move(p)] () mutable {
            return _l3.send(e_dst, std::move(p));
        }).then([this] {
            _send_sem.signal();
        });
    });
}

void ipv4::set_host_address(ipv4_address ip) {
    _host_address = ip;
    _arp.set_self_addr(ip);
}

void checksummer::sum(const char* data, size_t len) {
    auto orig_len = len;
    if (odd) {
        partial += uint8_t(*data++);
        --len;
    }
    partial += ip_checksum(data, len);
    odd ^= orig_len & 1;
}

void checksummer::sum(const packet& p) {
    for (auto&& f : p.fragments) {
        sum(f.base, f.size);
    }
}

uint16_t checksummer::get() const {
    return partial + (partial >> 16);
}

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 GitHub, Inc.
 *
 * 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.
 */
#include <dlfcn.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#include "bcc_elf.h"
#include "bcc_proc.h"
#include "bcc_syms.h"

#include "catch.hpp"

using namespace std;

TEST_CASE("shared object resolution", "[c_api]") {
  const char *libm = bcc_procutils_which_so("m");
  REQUIRE(libm);
  REQUIRE(libm[0] == '/');
  REQUIRE(string(libm).find("libm.so") != string::npos);
}

TEST_CASE("binary resolution with `which`", "[c_api]") {
  char *ld = bcc_procutils_which("ld");
  REQUIRE(ld);
  REQUIRE(ld[0] == '/');
  free(ld);
}

static void _test_ksym(const char *sym, uint64_t addr, void *_) {
  if (!strcmp(sym, "startup_64")) {
    REQUIRE(addr == 0xffffffff81000000ull);
  } else if (!strcmp(sym, "__per_cpu_start"))
    REQUIRE(addr == 0x0);
}

TEST_CASE("list all kernel symbols", "[c_api]") {
  if (geteuid() != 0)
    return;
  bcc_procutils_each_ksym(_test_ksym, NULL);
}

TEST_CASE("resolve symbol name in external library", "[c_api]") {
  struct bcc_symbol sym;

  REQUIRE(bcc_resolve_symname("c", "malloc", 0x0, &sym) == 0);
  REQUIRE(string(sym.module).find("libc.so") != string::npos);
  REQUIRE(sym.module[0] == '/');
  REQUIRE(sym.offset != 0);
}

extern "C" int _a_test_function(const char *a_string) {
  int i;
  for (i = 0; a_string[i]; ++i)
    ;
  return i;
}

TEST_CASE("resolve symbol addresses for a given PID", "[c_api]") {
  struct bcc_symbol sym;
  void *resolver = bcc_symcache_new(getpid());

  REQUIRE(resolver);

  SECTION("resolve in our own binary memory space") {
    REQUIRE(bcc_symcache_resolve(resolver, (uint64_t)&_a_test_function, &sym) ==
            0);

    char *this_exe = realpath("/proc/self/exe", NULL);
    REQUIRE(string(this_exe) == sym.module);
    free(this_exe);

    REQUIRE(string("_a_test_function") == sym.name);
  }

  SECTION("resolve in libbcc.so") {
    void *libbcc = dlopen("libbcc.so", RTLD_LAZY | RTLD_NOLOAD);
    REQUIRE(libbcc);

    void *libbcc_fptr = dlsym(libbcc, "bcc_resolve_symname");
    REQUIRE(libbcc_fptr);

    REQUIRE(bcc_symcache_resolve(resolver, (uint64_t)libbcc_fptr, &sym) == 0);
    REQUIRE(string(sym.module).find("libbcc.so") != string::npos);
    REQUIRE(string("bcc_resolve_symname") == sym.name);
  }

  SECTION("resolve in libc") {
    void *libc_fptr = dlsym(NULL, "strtok");
    REQUIRE(libc_fptr);

    REQUIRE(bcc_symcache_resolve(resolver, (uint64_t)libc_fptr, &sym) == 0);
    REQUIRE(sym.module);
    REQUIRE(sym.module[0] == '/');
    REQUIRE(string(sym.module).find("libc") != string::npos);
    REQUIRE(string("strtok") == sym.name);
  }
}
<commit_msg>tests: only test arch-specific symbols<commit_after>/*
 * Copyright (c) 2016 GitHub, Inc.
 *
 * 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.
 */
#include <dlfcn.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#include "bcc_elf.h"
#include "bcc_proc.h"
#include "bcc_syms.h"

#include "catch.hpp"

using namespace std;

TEST_CASE("shared object resolution", "[c_api]") {
  const char *libm = bcc_procutils_which_so("m");
  REQUIRE(libm);
  REQUIRE(libm[0] == '/');
  REQUIRE(string(libm).find("libm.so") != string::npos);
}

TEST_CASE("binary resolution with `which`", "[c_api]") {
  char *ld = bcc_procutils_which("ld");
  REQUIRE(ld);
  REQUIRE(ld[0] == '/');
  free(ld);
}

static void _test_ksym(const char *sym, uint64_t addr, void *_) {
  if (!strcmp(sym, "startup_64")) {
    REQUIRE(addr == 0xffffffff81000000ull);
  } else if (!strcmp(sym, "system_reset_pSeries"))
    REQUIRE(addr == 0xc000000000000100ull);
}

TEST_CASE("list all kernel symbols", "[c_api]") {
  if (geteuid() != 0)
    return;
  bcc_procutils_each_ksym(_test_ksym, NULL);
}

TEST_CASE("resolve symbol name in external library", "[c_api]") {
  struct bcc_symbol sym;

  REQUIRE(bcc_resolve_symname("c", "malloc", 0x0, &sym) == 0);
  REQUIRE(string(sym.module).find("libc.so") != string::npos);
  REQUIRE(sym.module[0] == '/');
  REQUIRE(sym.offset != 0);
}

extern "C" int _a_test_function(const char *a_string) {
  int i;
  for (i = 0; a_string[i]; ++i)
    ;
  return i;
}

TEST_CASE("resolve symbol addresses for a given PID", "[c_api]") {
  struct bcc_symbol sym;
  void *resolver = bcc_symcache_new(getpid());

  REQUIRE(resolver);

  SECTION("resolve in our own binary memory space") {
    REQUIRE(bcc_symcache_resolve(resolver, (uint64_t)&_a_test_function, &sym) ==
            0);

    char *this_exe = realpath("/proc/self/exe", NULL);
    REQUIRE(string(this_exe) == sym.module);
    free(this_exe);

    REQUIRE(string("_a_test_function") == sym.name);
  }

  SECTION("resolve in libbcc.so") {
    void *libbcc = dlopen("libbcc.so", RTLD_LAZY | RTLD_NOLOAD);
    REQUIRE(libbcc);

    void *libbcc_fptr = dlsym(libbcc, "bcc_resolve_symname");
    REQUIRE(libbcc_fptr);

    REQUIRE(bcc_symcache_resolve(resolver, (uint64_t)libbcc_fptr, &sym) == 0);
    REQUIRE(string(sym.module).find("libbcc.so") != string::npos);
    REQUIRE(string("bcc_resolve_symname") == sym.name);
  }

  SECTION("resolve in libc") {
    void *libc_fptr = dlsym(NULL, "strtok");
    REQUIRE(libc_fptr);

    REQUIRE(bcc_symcache_resolve(resolver, (uint64_t)libc_fptr, &sym) == 0);
    REQUIRE(sym.module);
    REQUIRE(sym.module[0] == '/');
    REQUIRE(string(sym.module).find("libc") != string::npos);
    REQUIRE(string("strtok") == sym.name);
  }
}
<|endoftext|>


<commit_before><commit_msg>COMP-8312: Fixed start_container_sync() method so that it invokes acsutilAwaitContainerStart instead of acsStartContainer<commit_after><|endoftext|>


<commit_before>#include <cstring>

#if defined _OPENMP
#include <omp.h>
#else
#define omp_get_thread_num()  0
#endif

#ifdef _MSC_VER
#pragma warning(disable:4127)
#endif
#define __DYN_GRID_SIZE
#include "common.h"
#include "metrix.h"
#include "OskarBinReader.h"
#include "aligned_malloc.h"

#define as256p(p) (reinterpret_cast<__m256d*>(p))
#define as256pc(p) (reinterpret_cast<const __m256d*>(p))

inline
void addGrids(
    complexd dst[]
  , const complexd srcs[]
  , int nthreads
  , int grid_pitch
  , int grid_size
  )
{
  int siz = grid_size*grid_pitch;
#pragma omp parallel for
  for (unsigned int i = 0; i < siz*sizeof(complexd)/(256/8); i++) {
    __m256d sum = as256pc(srcs)[i];
    // __m256d sum = _mm256_loadu_pd(reinterpret_cast<const double*>(as256pc(srcs)+i));

    for (int g = 1; g < nthreads; g ++)
      sum = _mm256_add_pd(sum, as256pc(srcs + g * siz)[i]);

    as256p(dst)[i] = sum;
  }
}

// We could simply use pointer-to-function template
// but most C++ compilers seem to produce worse code
// in such a case. Thus we wrap it in a class.
template <
    int over
  , bool do_mirror
  , typename Inp
  > struct cvt {};

template <
    int over
  , bool do_mirror
  > struct cvt<over, do_mirror, Pregridded> {
  static void pre(double, double, Pregridded inp, Pregridded & outpr, int) {outpr = inp;}
};

template <
    int over
  , bool do_mirror
  > struct cvt<over, do_mirror, Double3> {
  static void pre(double scale, double wstep, Double3 inp, Pregridded & outpr, int grid_size) {
    pregridPoint<over, do_mirror>(scale, wstep, inp, outpr, grid_size);
  }
};

template <
    int over
  , bool is_half_gcf
  , bool use_permutations

  , typename Inp
  >
// grid must be initialized to 0s.
void gridKernel_scatter(
    double scale
  , double wstep
  , int baselines
  , const BlWMap permutations[/* baselines */]
  , complexd grids[]
    // We have a [w_planes][over][over]-shaped array of pointers to
    // variable-sized gcf layers, but we precompute (in pregrid)
    // exact index into this array, thus we use plain pointer here
  , const complexd * gcf[]
  , const Inp _uvw[]
  , const complexd _vis[]
  , int ts_ch
  , int grid_pitch
  , int grid_size
  ) {
  int siz = grid_size*grid_pitch;
#pragma omp parallel
  {
    complexd * _grid = grids + omp_get_thread_num() * siz;
    memset(_grid, 0, sizeof(complexd) * siz);
    __ACC(complexd, grid, grid_pitch);

#pragma omp for schedule(dynamic)
    for(int bl0 = 0; bl0 < baselines; bl0++) {
      int bl;
      if (use_permutations) bl = permutations[bl0].bl;
      else bl = bl0;
      int max_supp_here;
      max_supp_here = get_supp(permutations[bl].wp);

      // Rotation
      // VLA requires "--std=gnu..." extension
      complexd vis[ts_ch];
      int off;
      off = bl*ts_ch;
      const Inp * uvw;
      uvw = _uvw + off;
      for(int n=0; n<ts_ch; n++){
        vis[n] = rotw(_vis[off + n], uvw[n].w);
      }

      for (int su = 0; su < max_supp_here; su++) { // Moved from 2-levels below according to Romein
        for (int i = 0; i < ts_ch; i++) {
            Pregridded p;
            cvt<over, is_half_gcf, Inp>::pre(scale, wstep, uvw[i], p, grid_size);

          for (int sv = 0; sv < max_supp_here; sv++) {
            // Don't forget our u v are already translated by -max_supp_here/2
            int gsu, gsv;
            gsu = p.u + su;
            gsv = p.v + sv;

            complexd supportPixel;
            #define __layeroff su * max_supp_here + sv
            if (is_half_gcf) {
              int index;
              index = p.gcf_layer_index;
              // Negative index indicates that original w was mirrored
              // and we shall negate the index to obtain correct
              // offset *and* conjugate the result.
              if (index < 0) {
                supportPixel = conj(gcf[-index][__layeroff]);
              } else {
                supportPixel = gcf[index][__layeroff];
              }
            } else {
                supportPixel = gcf[p.gcf_layer_index][__layeroff];
            }

            grid[gsu][gsv] += vis[i] * supportPixel;
          }
        }
      }
    }
  }
}

template <
    int over
  , bool is_half_gcf
  , bool use_permutations

  , typename Inp
  >
// grid must be initialized to 0s.
void gridKernel_scatter_full(
    double scale
  , double wstep
  , int baselines
  , const BlWMap permutations[/* baselines */]
  , complexd grid[]
    // We have a [w_planes][over][over]-shaped array of pointers to
    // variable-sized gcf layers, but we precompute (in pregrid)
    // exact index into this array, thus we use plain pointer here
  , const complexd * gcf[]
  , const Inp uvw[]
  , const complexd vis[]
  , int ts_ch
  , int grid_pitch
  , int grid_size
  ) {
#if defined _OPENMP
  int siz = grid_size*grid_pitch;
  int nthreads;

#pragma omp parallel
#pragma omp single
  nthreads = omp_get_num_threads();

  // Nullify incoming grid, allocate thread-local grids
  memset(grid, 0, sizeof(complexd) * siz);
  complexd * tmpgrids = alignedMallocArray<complexd>(siz * nthreads, 32);

  gridKernel_scatter<
      over
    , is_half_gcf
    , use_permutations

    , Inp
    >(scale, wstep, baselines, permutations, tmpgrids, gcf, uvw, vis, ts_ch, grid_pitch, grid_size);
  addGrids(grid, tmpgrids, nthreads, grid_pitch, grid_size);
  free(tmpgrids);
#else
  gridKernel_scatter<
      over
    , is_half_gcf
    , use_permutations

    , Inp
    >(scale, wstep, baselines, permutations, grid, gcf, uvw, vis, ts_ch, grid_pitch, grid_size);
#endif
}

#define gridKernelCPU(hgcfSuff, isHgcf, permSuff, isPerm)  \
extern "C"                                                 \
void gridKernelCPU##hgcfSuff##permSuff(                    \
    double scale                                           \
  , double wstep                                           \
  , int baselines                                          \
  , const BlWMap permutations[/* baselines */]             \
  , complexd grid[]                                        \
  , const complexd * gcf[]                                 \
  , const Double3 uvw[]                                    \
  , const complexd vis[]                                   \
  , int ts_ch                                              \
  , int grid_pitch                                         \
  , int grid_size                                          \
  ){                                                       \
  gridKernel_scatter_full<OVER, isHgcf, isPerm>            \
    ( scale, wstep, baselines, permutations                \
    , grid, gcf, uvw, vis, ts_ch, grid_pitch, grid_size);  \
}

gridKernelCPU(HalfGCF, true, Perm, true)
gridKernelCPU(HalfGCF, true, , false)
gridKernelCPU(FullGCF, false, Perm, true)
gridKernelCPU(FullGCF, false, , false)

// Normalization is done inplace!
extern "C"
void normalize(
    int n
  , complexd src[]
  , int grid_pitch
  , int grid_size
  )
{
  int siz = grid_size*grid_pitch;
  double norm = 1.0/double(siz);
#pragma omp parallel for
  for (int i = 0; i < siz; i++) {
    src[i] *= norm;
  }
}
<commit_msg>Added CPU degridder. Didn't bother to write much new code, basically swapped grid and viz data in existing gridder code.<commit_after>#include <cstring>

#if defined _OPENMP
#include <omp.h>
#else
#define omp_get_thread_num()  0
#endif

#ifdef _MSC_VER
#pragma warning(disable:4127)
#endif
#define __DYN_GRID_SIZE
#include "common.h"
#include "metrix.h"
#include "OskarBinReader.h"
#include "aligned_malloc.h"

#define as256p(p) (reinterpret_cast<__m256d*>(p))
#define as256pc(p) (reinterpret_cast<const __m256d*>(p))

#ifndef __DEGRID
#define GRID_MOD
#define VIS_MOD const
inline
void addGrids(
    complexd dst[]
  , const complexd srcs[]
  , int nthreads
  , int grid_pitch
  , int grid_size
  )
{
  int siz = grid_size*grid_pitch;
#pragma omp parallel for
  for (unsigned int i = 0; i < siz*sizeof(complexd)/(256/8); i++) {
    __m256d sum = as256pc(srcs)[i];
    // __m256d sum = _mm256_loadu_pd(reinterpret_cast<const double*>(as256pc(srcs)+i));

    for (int g = 1; g < nthreads; g ++)
      sum = _mm256_add_pd(sum, as256pc(srcs + g * siz)[i]);

    as256p(dst)[i] = sum;
  }
}
#else
#define GRID_MOD const
#define VIS_MOD
#endif

// We could simply use pointer-to-function template
// but most C++ compilers seem to produce worse code
// in such a case. Thus we wrap it in a class.
template <
    int over
  , bool do_mirror
  , typename Inp
  > struct cvt {};

template <
    int over
  , bool do_mirror
  > struct cvt<over, do_mirror, Pregridded> {
  static void pre(double, double, Pregridded inp, Pregridded & outpr, int) {outpr = inp;}
};

template <
    int over
  , bool do_mirror
  > struct cvt<over, do_mirror, Double3> {
  static void pre(double scale, double wstep, Double3 inp, Pregridded & outpr, int grid_size) {
    pregridPoint<over, do_mirror>(scale, wstep, inp, outpr, grid_size);
  }
};

template <
    int over
  , bool is_half_gcf
  , bool use_permutations

  , typename Inp
  >
// grid must be initialized to 0s.
void gridKernel_scatter(
    double scale
  , double wstep
  , int baselines
  , const BlWMap permutations[/* baselines */]
  , GRID_MOD complexd grids[]
    // We have a [w_planes][over][over]-shaped array of pointers to
    // variable-sized gcf layers, but we precompute (in pregrid)
    // exact index into this array, thus we use plain pointer here
  , const complexd * gcf[]
  , const Inp _uvw[]
  , VIS_MOD complexd _vis[]
  , int ts_ch
  , int grid_pitch
  , int grid_size
  ) {
  int siz = grid_size*grid_pitch;
#pragma omp parallel
  {
    GRID_MOD complexd * _grid = grids + omp_get_thread_num() * siz;
#ifndef __DEGRID
    memset(_grid, 0, sizeof(complexd) * siz);
#else
    memset(_vis, 0, sizeof(complexd) * baselines * ts_ch);
#endif
    __ACC(complexd, grid, grid_pitch);

#pragma omp for schedule(dynamic)
    for(int bl0 = 0; bl0 < baselines; bl0++) {
      int bl;
      if (use_permutations) bl = permutations[bl0].bl;
      else bl = bl0;
      int max_supp_here;
      max_supp_here = get_supp(permutations[bl].wp);

      int off;
      off = bl*ts_ch;
      const Inp * uvw;
      uvw = _uvw + off;
#ifndef __DEGRID
      // Rotation
      // VLA requires "--std=gnu..." extension
      complexd vis[ts_ch];
      for(int n=0; n<ts_ch; n++){
        vis[n] = rotw(_vis[off + n], uvw[n].w);
      }
#else
      complexd * vis;
      vis = _vis + off;
#endif
      for (int su = 0; su < max_supp_here; su++) { // Moved from 2-levels below according to Romein
        for (int i = 0; i < ts_ch; i++) {
            Pregridded p;
            cvt<over, is_half_gcf, Inp>::pre(scale, wstep, uvw[i], p, grid_size);

          for (int sv = 0; sv < max_supp_here; sv++) {
            // Don't forget our u v are already translated by -max_supp_here/2
            int gsu, gsv;
            gsu = p.u + su;
            gsv = p.v + sv;

            complexd supportPixel;
            #define __layeroff su * max_supp_here + sv
            if (is_half_gcf) {
              int index;
              index = p.gcf_layer_index;
              // Negative index indicates that original w was mirrored
              // and we shall negate the index to obtain correct
              // offset *and* conjugate the result.
              if (index < 0) {
                supportPixel = conj(gcf[-index][__layeroff]);
              } else {
                supportPixel = gcf[index][__layeroff];
              }
            } else {
                supportPixel = gcf[p.gcf_layer_index][__layeroff];
            }
#ifndef __DEGRID
            grid[gsu][gsv] += vis[i] * supportPixel;
#else
            vis[i] += rotw(grid[gsu][gsv] * supportPixel, uvw[i].w);
#endif
          }
        }
      }
    }
  }
}

#ifndef __DEGRID
template <
    int over
  , bool is_half_gcf
  , bool use_permutations

  , typename Inp
  >
// grid must be initialized to 0s.
void gridKernel_scatter_full(
    double scale
  , double wstep
  , int baselines
  , const BlWMap permutations[/* baselines */]
  , complexd grid[]
    // We have a [w_planes][over][over]-shaped array of pointers to
    // variable-sized gcf layers, but we precompute (in pregrid)
    // exact index into this array, thus we use plain pointer here
  , const complexd * gcf[]
  , const Inp uvw[]
  , const complexd vis[]
  , int ts_ch
  , int grid_pitch
  , int grid_size
  ) {
#if defined _OPENMP
  int siz = grid_size*grid_pitch;
  int nthreads;

#pragma omp parallel
#pragma omp single
  nthreads = omp_get_num_threads();

  // Nullify incoming grid, allocate thread-local grids
  memset(grid, 0, sizeof(complexd) * siz);
  complexd * tmpgrids = alignedMallocArray<complexd>(siz * nthreads, 32);

  gridKernel_scatter<
      over
    , is_half_gcf
    , use_permutations

    , Inp
    >(scale, wstep, baselines, permutations, tmpgrids, gcf, uvw, vis, ts_ch, grid_pitch, grid_size);
  addGrids(grid, tmpgrids, nthreads, grid_pitch, grid_size);
  free(tmpgrids);
#else
  gridKernel_scatter<
      over
    , is_half_gcf
    , use_permutations

    , Inp
    >(scale, wstep, baselines, permutations, grid, gcf, uvw, vis, ts_ch, grid_pitch, grid_size);
#endif
}

#define gridKernelCPU(hgcfSuff, isHgcf, permSuff, isPerm)  \
extern "C"                                                 \
void gridKernelCPU##hgcfSuff##permSuff(                    \
    double scale                                           \
  , double wstep                                           \
  , int baselines                                          \
  , const BlWMap permutations[/* baselines */]             \
  , complexd grid[]                                        \
  , const complexd * gcf[]                                 \
  , const Double3 uvw[]                                    \
  , const complexd vis[]                                   \
  , int ts_ch                                              \
  , int grid_pitch                                         \
  , int grid_size                                          \
  ){                                                       \
  gridKernel_scatter_full<OVER, isHgcf, isPerm>            \
    ( scale, wstep, baselines, permutations                \
    , grid, gcf, uvw, vis, ts_ch, grid_pitch, grid_size);  \
}

gridKernelCPU(HalfGCF, true, Perm, true)
gridKernelCPU(HalfGCF, true, , false)
gridKernelCPU(FullGCF, false, Perm, true)
gridKernelCPU(FullGCF, false, , false)

// Normalization is done inplace!
extern "C"
void normalize(
    int n
  , complexd src[]
  , int grid_pitch
  , int grid_size
  )
{
  int siz = grid_size*grid_pitch;
  double norm = 1.0/double(siz);
#pragma omp parallel for
  for (int i = 0; i < siz; i++) {
    src[i] *= norm;
  }
}

#else

#define deGridKernelCPU(hgcfSuff, isHgcf, permSuff, isPerm) \
extern "C"                                                  \
void deGridKernelCPU##hgcfSuff##permSuff(                   \
    double scale                                            \
  , double wstep                                            \
  , int baselines                                           \
  , const BlWMap permutations[/* baselines */]              \
  , const complexd grid[]                                   \
  , const complexd * gcf[]                                  \
  , const Double3 uvw[]                                     \
  , complexd vis[]                                          \
  , int ts_ch                                               \
  , int grid_pitch                                          \
  , int grid_size                                           \
  ){                                                        \
  gridKernel_scatter<OVER, isHgcf, isPerm>                  \
    ( scale, wstep, baselines, permutations                 \
    , grid, gcf, uvw, vis, ts_ch, grid_pitch, grid_size);   \
}

deGridKernelCPU(HalfGCF, true, Perm, true)
deGridKernelCPU(HalfGCF, true, , false)
deGridKernelCPU(FullGCF, false, Perm, true)
deGridKernelCPU(FullGCF, false, , false)

#endif
<|endoftext|>


<commit_before><commit_msg>Fixed the issue with the varibles of the function not being initalised in the contructor with both Progenetor fraction as well as the other missing varibles. Additionally Moved some initlisation of later varibles in the run loop, to fix a bug that was cropping up with labling the pdg codes of empty jets<commit_after><|endoftext|>


<commit_before>#include "../../src/svgdom/dom.hpp"

#include <clocale>

#include <utki/debug.hpp>

#include <papki/fs_file.hpp>

int main(int argc, char** argv){
	std::string filename;
	switch(argc){
		case 0:
		case 1:
			std::cout << "Warning: expected 1 argument: <svg-file>" << std::endl;
			std::cout << "\tGot 0 arguments, assuming <svg-file>=tiger.svg" << std::endl;
			filename = "tiger.svg";
			break;
		default:
		case 2:
			filename = argv[1];
			break;
	}

	// make sure the locale does not affect parsing (decimal delimiter can be "." or "," in different locales)
	// so, set DE locale which has "," to make sure it does not affect the parsing
	std::setlocale(LC_ALL, "de_DE.UTF-8");

	auto dom = svgdom::load(papki::fs_file(filename));

//	TRACE_ALWAYS(<< "file read" << std::endl)

	ASSERT_ALWAYS(dom)

	auto str = dom->to_string();
//	TRACE_ALWAYS(<< str << std::endl)

	papki::fs_file out_file("out.svg");
	papki::file::guard file_guard(out_file, papki::file::mode::create);
	out_file.write(utki::make_span(str));
}
<commit_msg>set test locale but and print warning in case of error<commit_after>#include "../../src/svgdom/dom.hpp"

#include <clocale>

#include <utki/debug.hpp>

#include <papki/fs_file.hpp>

int main(int argc, char** argv){
	std::string filename;
	switch(argc){
		case 0:
		case 1:
			std::cout << "Warning: expected 1 argument: <svg-file>" << std::endl;
			std::cout << "\tGot 0 arguments, assuming <svg-file>=tiger.svg" << std::endl;
			filename = "tiger.svg";
			break;
		default:
		case 2:
			filename = argv[1];
			break;
	}

	// make sure the locale does not affect parsing (decimal delimiter can be "." or "," in different locales)
	// so, set DE locale which has "," to make sure it does not affect the parsing
	if(!std::setlocale(LC_ALL, "de_DE.UTF-8")){
		utki::log([](auto& o){o << "WARNING: failed to set locale de_DE.UTF-8, perhaps the locale is not installed. Testing that locale does not affect parsing will not be done.";});
	}

	auto dom = svgdom::load(papki::fs_file(filename));

//	TRACE_ALWAYS(<< "file read" << std::endl)

	ASSERT_ALWAYS(dom)

	auto str = dom->to_string();
//	TRACE_ALWAYS(<< str << std::endl)

	papki::fs_file out_file("out.svg");
	papki::file::guard file_guard(out_file, papki::file::mode::create);
	out_file.write(utki::make_span(str));
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2015 The Bitsend developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "core.h"
#include "util.h"
#include "main.h"
#include "uint256.h"

std::string COutPoint::ToString() const
{
    return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,64), n);
}

void COutPoint::print() const
{
    LogPrintf("%s\n", ToString());
}

CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, unsigned int nSequenceIn)
{
    prevout = prevoutIn;
    scriptSig = scriptSigIn;
    nSequence = nSequenceIn;
}

CTxIn::CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn, unsigned int nSequenceIn)
{
    prevout = COutPoint(hashPrevTx, nOut);
    scriptSig = scriptSigIn;
    nSequence = nSequenceIn;
}

std::string CTxIn::ToString() const
{
    std::string str;
    str += "CTxIn(";
    str += prevout.ToString();
    if (prevout.IsNull())
        str += strprintf(", coinbase %s", HexStr(scriptSig));
    else
        str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24));
    if (nSequence != std::numeric_limits<unsigned int>::max())
        str += strprintf(", nSequence=%u", nSequence);
    str += ")";
    return str;
}

void CTxIn::print() const
{
    LogPrintf("%s\n", ToString());
}

CTxOut::CTxOut(int64_t nValueIn, CScript scriptPubKeyIn)
{
    nValue = nValueIn;
    nRounds = -10; // an initial value, should be no way to get this by calculations
    scriptPubKey = scriptPubKeyIn;
}

uint256 CTxOut::GetHash() const
{
    return SerializeHash(*this);
}

std::string CTxOut::ToString() const
{
    return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30));
}

void CTxOut::print() const
{
    LogPrintf("%s\n", ToString());
}

uint256 CTransaction::GetHash() const
{
    return SerializeHash(*this);
}

bool CTransaction::IsNewerThan(const CTransaction& old) const
{
    if (vin.size() != old.vin.size())
        return false;
    for (unsigned int i = 0; i < vin.size(); i++)
        if (vin[i].prevout != old.vin[i].prevout)
            return false;

    bool fNewer = false;
    unsigned int nLowest = std::numeric_limits<unsigned int>::max();
    for (unsigned int i = 0; i < vin.size(); i++)
    {
        if (vin[i].nSequence != old.vin[i].nSequence)
        {
            if (vin[i].nSequence <= nLowest)
            {
                fNewer = false;
                nLowest = vin[i].nSequence;
            }
            if (old.vin[i].nSequence < nLowest)
            {
                fNewer = true;
                nLowest = old.vin[i].nSequence;
            }
        }
    }
    return fNewer;
}

int64_t CTransaction::GetValueOut() const
{
    int64_t nValueOut = 0;
    BOOST_FOREACH(const CTxOut& txout, vout)
    {
        nValueOut += txout.nValue;
        if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
            throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
    }
    return nValueOut;
}

double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const
{
    // In order to avoid disincentivizing cleaning up the UTXO set we don't count
    // the constant overhead for each txin and up to 110 bytes of scriptSig (which
    // is enough to cover a compressed pubkey p2sh redemption) for priority.
    // Providing any more cleanup incentive than making additional inputs free would
    // risk encouraging people to create junk outputs to redeem later.
    if (nTxSize == 0)
        nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
    BOOST_FOREACH(const CTxIn& txin, vin)
    {
        unsigned int offset = 41U + std::min(110U, (unsigned int)txin.scriptSig.size());
        if (nTxSize > offset)
            nTxSize -= offset;
    }
    if (nTxSize == 0) return 0.0;
    return dPriorityInputs / nTxSize;
}

std::string CTransaction::ToString() const
{
    std::string str;
    str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
        GetHash().ToString().substr(0,10),
        nVersion,
        vin.size(),
        vout.size(),
        nLockTime);
    for (unsigned int i = 0; i < vin.size(); i++)
        str += "    " + vin[i].ToString() + "\n";
    for (unsigned int i = 0; i < vout.size(); i++)
        str += "    " + vout[i].ToString() + "\n";
    return str;
}

void CTransaction::print() const
{
    LogPrintf("%s", ToString());
}

// Amount compression:
// * If the amount is 0, output 0
// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9)
// * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10)
//   * call the result n
//   * output 1 + 10*(9*n + d - 1) + e
// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9
// (this is decodable, as d is in [1-9] and e is in [0-9])

uint64_t CTxOutCompressor::CompressAmount(uint64_t n)
{
    if (n == 0)
        return 0;
    int e = 0;
    while (((n % 10) == 0) && e < 9) {
        n /= 10;
        e++;
    }
    if (e < 9) {
        int d = (n % 10);
        assert(d >= 1 && d <= 9);
        n /= 10;
        return 1 + (n*9 + d - 1)*10 + e;
    } else {
        return 1 + (n - 1)*10 + 9;
    }
}

uint64_t CTxOutCompressor::DecompressAmount(uint64_t x)
{
    // x = 0  OR  x = 1+10*(9*n + d - 1) + e  OR  x = 1+10*(n - 1) + 9
    if (x == 0)
        return 0;
    x--;
    // x = 10*(9*n + d - 1) + e
    int e = x % 10;
    x /= 10;
    uint64_t n = 0;
    if (e < 9) {
        // x = 9*n + d - 1
        int d = (x % 9) + 1;
        x /= 9;
        // x = n
        n = x*10 + d;
    } else {
        n = x+1;
    }
    while (e) {
        n *= 10;
        e--;
    }
    return n;
}
/*uint256 CBlockHeader::GetHash() const
{
	CChain a1;
	int nHeight= a1.Height();
	//pblock->LastHeight = pindexPrev->nHeight;
	if (nHeight <=10){
    return HashX11(BEGIN(nVersion), END(nNonce));
	}
    else {
	   return HashX17(BEGIN(nVersion), END(nNonce));
	}
}*/

uint256 CBlockHeader::GetHashX11() const
{
    return HashX11(BEGIN(nVersion), END(nNonce));
}

uint256 CBlock::BuildMerkleTree() const
{
    vMerkleTree.clear();
    BOOST_FOREACH(const CTransaction& tx, vtx)
        vMerkleTree.push_back(tx.GetHash());
    int j = 0;
    for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
    {
        for (int i = 0; i < nSize; i += 2)
        {
            int i2 = std::min(i+1, nSize-1);
            vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]),  END(vMerkleTree[j+i]),
                                       BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
        }
        j += nSize;
    }
    return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
}

std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
{
    if (vMerkleTree.empty())
        BuildMerkleTree();
    std::vector<uint256> vMerkleBranch;
    int j = 0;
    for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
    {
        int i = std::min(nIndex^1, nSize-1);
        vMerkleBranch.push_back(vMerkleTree[j+i]);
        nIndex >>= 1;
        j += nSize;
    }
    return vMerkleBranch;
}

uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
{
    if (nIndex == -1)
        return 0;
    BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
    {
        if (nIndex & 1)
            hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
        else
            hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
        nIndex >>= 1;
    }
    return hash;
}

void CBlock::print() const
{
	//GetHashX11().ToString(),
    LogPrintf("CBlock(hash=disable, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
        nVersion,
        hashPrevBlock.ToString(),
        hashMerkleRoot.ToString(),
        nTime, nBits, nNonce,
        vtx.size());
    for (unsigned int i = 0; i < vtx.size(); i++)
    {
        LogPrintf("  ");
        vtx[i].print();
    }
    LogPrintf("  vMerkleTree: ");
    for (unsigned int i = 0; i < vMerkleTree.size(); i++)
        LogPrintf("%s ", vMerkleTree[i].ToString());
    LogPrintf("\n");
}
<commit_msg>New way from line 229 to 36<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2015 The Bitsend developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "core.h"
#include "util.h"
#include "main.h"
#include "uint256.h"

std::string COutPoint::ToString() const
{
    return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,64), n);
}

void COutPoint::print() const
{
    LogPrintf("%s\n", ToString());
}

CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, unsigned int nSequenceIn)
{
    prevout = prevoutIn;
    scriptSig = scriptSigIn;
    nSequence = nSequenceIn;
}

CTxIn::CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn, unsigned int nSequenceIn)
{
    prevout = COutPoint(hashPrevTx, nOut);
    scriptSig = scriptSigIn;
    nSequence = nSequenceIn;
}

std::string CTxIn::ToString() const
{
    std::string str;
    str += "CTxIn(";
    str += prevout.ToString();
    if (prevout.IsNull())
        str += strprintf(", coinbase %s", HexStr(scriptSig));
    else
        str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24));
    if (nSequence != std::numeric_limits<unsigned int>::max())
        str += strprintf(", nSequence=%u", nSequence);
    str += ")";
    return str;
}

void CTxIn::print() const
{
    LogPrintf("%s\n", ToString());
}

CTxOut::CTxOut(int64_t nValueIn, CScript scriptPubKeyIn)
{
    nValue = nValueIn;
    nRounds = -10; // an initial value, should be no way to get this by calculations
    scriptPubKey = scriptPubKeyIn;
}

uint256 CTxOut::GetHash() const
{
    return SerializeHash(*this);
}

std::string CTxOut::ToString() const
{
    return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30));
}

void CTxOut::print() const
{
    LogPrintf("%s\n", ToString());
}

uint256 CTransaction::GetHash() const
{
    return SerializeHash(*this);
}

bool CTransaction::IsNewerThan(const CTransaction& old) const
{
    if (vin.size() != old.vin.size())
        return false;
    for (unsigned int i = 0; i < vin.size(); i++)
        if (vin[i].prevout != old.vin[i].prevout)
            return false;

    bool fNewer = false;
    unsigned int nLowest = std::numeric_limits<unsigned int>::max();
    for (unsigned int i = 0; i < vin.size(); i++)
    {
        if (vin[i].nSequence != old.vin[i].nSequence)
        {
            if (vin[i].nSequence <= nLowest)
            {
                fNewer = false;
                nLowest = vin[i].nSequence;
            }
            if (old.vin[i].nSequence < nLowest)
            {
                fNewer = true;
                nLowest = old.vin[i].nSequence;
            }
        }
    }
    return fNewer;
}

int64_t CTransaction::GetValueOut() const
{
    int64_t nValueOut = 0;
    BOOST_FOREACH(const CTxOut& txout, vout)
    {
        nValueOut += txout.nValue;
        if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
            throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
    }
    return nValueOut;
}

double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const
{
    // In order to avoid disincentivizing cleaning up the UTXO set we don't count
    // the constant overhead for each txin and up to 110 bytes of scriptSig (which
    // is enough to cover a compressed pubkey p2sh redemption) for priority.
    // Providing any more cleanup incentive than making additional inputs free would
    // risk encouraging people to create junk outputs to redeem later.
    if (nTxSize == 0)
        nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
    BOOST_FOREACH(const CTxIn& txin, vin)
    {
        unsigned int offset = 41U + std::min(110U, (unsigned int)txin.scriptSig.size());
        if (nTxSize > offset)
            nTxSize -= offset;
    }
    if (nTxSize == 0) return 0.0;
    return dPriorityInputs / nTxSize;
}

std::string CTransaction::ToString() const
{
    std::string str;
    str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
        GetHash().ToString().substr(0,10),
        nVersion,
        vin.size(),
        vout.size(),
        nLockTime);
    for (unsigned int i = 0; i < vin.size(); i++)
        str += "    " + vin[i].ToString() + "\n";
    for (unsigned int i = 0; i < vout.size(); i++)
        str += "    " + vout[i].ToString() + "\n";
    return str;
}

void CTransaction::print() const
{
    LogPrintf("%s", ToString());
}

// Amount compression:
// * If the amount is 0, output 0
// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9)
// * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10)
//   * call the result n
//   * output 1 + 10*(9*n + d - 1) + e
// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9
// (this is decodable, as d is in [1-9] and e is in [0-9])

uint64_t CTxOutCompressor::CompressAmount(uint64_t n)
{
    if (n == 0)
        return 0;
    int e = 0;
    while (((n % 10) == 0) && e < 9) {
        n /= 10;
        e++;
    }
    if (e < 9) {
        int d = (n % 10);
        assert(d >= 1 && d <= 9);
        n /= 10;
        return 1 + (n*9 + d - 1)*10 + e;
    } else {
        return 1 + (n - 1)*10 + 9;
    }
}

uint64_t CTxOutCompressor::DecompressAmount(uint64_t x)
{
    // x = 0  OR  x = 1+10*(9*n + d - 1) + e  OR  x = 1+10*(n - 1) + 9
    if (x == 0)
        return 0;
    x--;
    // x = 10*(9*n + d - 1) + e
    int e = x % 10;
    x /= 10;
    uint64_t n = 0;
    if (e < 9) {
        // x = 9*n + d - 1
        int d = (x % 9) + 1;
        x /= 9;
        // x = n
        n = x*10 + d;
    } else {
        n = x+1;
    }
    while (e) {
        n *= 10;
        e--;
    }
    return n;
}
/*uint256 CBlockHeader::GetHash() const
{
	CChain a1;
	int nHeight= a1.Height();
	//pblock->LastHeight = pindexPrev->nHeight;
	if (nHeight <=10){
    return HashX11(BEGIN(nVersion), END(nNonce));
	}
    else {
	   return HashX17(BEGIN(nVersion), END(nNonce));
	}
}*/
/*uint256 CBlockHeader::GetHash() const{
	if (LastHeight>=15){
    return HashX11(BEGIN(nVersion), END(nNonce));
	}
    else {
	   return HashX17(BEGIN(nVersion), END(nNonce));
	}
    }*/

uint256 CBlockHeader::GetHashX11() const
{
    return HashX11(BEGIN(nVersion), END(nNonce));
}

uint256 CBlock::BuildMerkleTree() const
{
    vMerkleTree.clear();
    BOOST_FOREACH(const CTransaction& tx, vtx)
        vMerkleTree.push_back(tx.GetHash());
    int j = 0;
    for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
    {
        for (int i = 0; i < nSize; i += 2)
        {
            int i2 = std::min(i+1, nSize-1);
            vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]),  END(vMerkleTree[j+i]),
                                       BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
        }
        j += nSize;
    }
    return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
}

std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
{
    if (vMerkleTree.empty())
        BuildMerkleTree();
    std::vector<uint256> vMerkleBranch;
    int j = 0;
    for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
    {
        int i = std::min(nIndex^1, nSize-1);
        vMerkleBranch.push_back(vMerkleTree[j+i]);
        nIndex >>= 1;
        j += nSize;
    }
    return vMerkleBranch;
}

uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
{
    if (nIndex == -1)
        return 0;
    BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
    {
        if (nIndex & 1)
            hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
        else
            hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
        nIndex >>= 1;
    }
    return hash;
}

void CBlock::print() const
{
	//GetHashX11().ToString(),
    LogPrintf("CBlock(hash=disable, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
        nVersion,
        hashPrevBlock.ToString(),
        hashMerkleRoot.ToString(),
        nTime, nBits, nNonce,
        vtx.size());
    for (unsigned int i = 0; i < vtx.size(); i++)
    {
        LogPrintf("  ");
        vtx[i].print();
    }
    LogPrintf("  vMerkleTree: ");
    for (unsigned int i = 0; i < vMerkleTree.size(); i++)
        LogPrintf("%s ", vMerkleTree[i].ToString());
    LogPrintf("\n");
}
<|endoftext|>