<commit_before>#include <ros/ros.h>
#include <cv_tracker/obj_label.h>
#include <lidar_tracker/centroids.h>
#include <visualization_msgs/Marker.h>
#include <visualization_msgs/MarkerArray.h>
#include <geometry_msgs/Point.h>
#include <math.h>
#include <float.h>
#include <tf/tf.h>
#include <tf/transform_listener.h>
#include <mutex>

/* flag for comfirming whether multiple topics are received */
static bool isReady_obj_label;
static bool isReady_cluster_centroids;

static constexpr uint32_t SUBSCRIBE_QUEUE_SIZE = 100;
static constexpr uint32_t ADVERTISE_QUEUE_SIZE = 10;
static constexpr bool ADVERTISE_LATCH = false;

ros::Publisher obj_pose_pub;

static std::vector<geometry_msgs::Point> reprojected_positions;
static std::string object_type;
static std::vector<geometry_msgs::Point> centroids;

static tf::StampedTransform transform;

/* mutex to handle objects from within multi thread safely */
std::mutex mtx_flag_obj_label;
std::mutex mtx_flag_cluster_centroids;
std::mutex mtx_reprojected_positions;
std::mutex mtx_centroids;
#define LOCK(mtx) (mtx).lock()
#define UNLOCK(mtx) (mtx).unlock()

static double euclid_distance(const geometry_msgs::Point pos1,
                              const geometry_msgs::Point pos2)
{
    return sqrt(pow(pos1.x - pos2.x, 2) +
                pow(pos1.y - pos2.y, 2) +
                pow(pos1.z - pos2.z, 2));

} /* static double distance() */

/* fusion reprojected position and pointcloud centroids */
static void fusion_objects(void)
{
    std::vector<geometry_msgs::Point> reprojected_positions_current;
    std::vector<geometry_msgs::Point> centroids_current;

    LOCK(mtx_reprojected_positions);
    copy(reprojected_positions.begin(), reprojected_positions.end(), back_inserter(reprojected_positions_current));
    UNLOCK(mtx_reprojected_positions);

    LOCK(mtx_centroids);
    copy(centroids.begin(), centroids.end(), back_inserter(centroids_current));
    UNLOCK(mtx_centroids);

    if (centroids_current.empty() || reprojected_positions_current.empty()) {
        return;
    }

    std::vector<unsigned int> obj_indices;
    for(const auto& reproj_pos : reprojected_positions_current)
        {
            unsigned int min_idx      = 0;
            double       min_distance = DBL_MAX;

            /* calculate each euclid distance between reprojected position and centroids */
            for (unsigned int i=0; i<centroids_current.size(); i++)
                {
                    double distance = euclid_distance(reproj_pos, centroids_current.at(i));

                    /* Nearest centroid correspond to this reprojected object */
                    if (distance < min_distance)
                        {
                            min_distance = distance;
                            min_idx      = i;
                        }
                }
            obj_indices.push_back(min_idx);
        }

    /* Publish marker with centroids coordinates */
    visualization_msgs::MarkerArray pub_msg;

    std_msgs::ColorRGBA color_red;
    color_red.r = 1.0f;
    color_red.g = 0.0f;
    color_red.b = 0.0f;
    color_red.a = 1.0f;

    std_msgs::ColorRGBA color_blue;
    color_blue.r = 0.0f;
    color_blue.g = 0.0f;
    color_blue.b = 1.0f;
    color_blue.a = 1.0f;

    std_msgs::ColorRGBA color_green;
    color_green.r = 0.0f;
    color_green.g = 1.0f;
    color_green.b = 0.0f;
    color_green.a = 1.0f;

    for (const auto& idx : obj_indices)
        {
            visualization_msgs::Marker marker;

            /*Set the frame ID */
            marker.header.frame_id = "map";

            /* Set the namespace and id for this marker */
            marker.ns = object_type;
            marker.id = idx;

            /* Set the marker type */
            marker.type = visualization_msgs::Marker::SPHERE;

            /* Set the pose of the marker */
            marker.pose.position = centroids_current.at(idx);
            marker.pose.orientation.x = 0.0;
            marker.pose.orientation.y = 0.0;
            marker.pose.orientation.y = 0.0;
            marker.pose.orientation.w = 0.0;

            /* Set the scale of the marker -- We assume object as 1.5m sphere */
            marker.scale.x = (double)1.5;
            marker.scale.y = (double)1.5;
            marker.scale.z = (double)1.5;

            /* Set the color */
            if (object_type == "car") {
                marker.color = color_blue;
            }
            else if (object_type == "person") {
                marker.color = color_green;
            }
            else {
                marker.color = color_red;
            }

            marker.lifetime = ros::Duration(0.3);

            pub_msg.markers.push_back(marker);
        }

        obj_pose_pub.publish(pub_msg);
}

void obj_label_cb(const cv_tracker::obj_label& obj_label_msg)
{
    object_type = obj_label_msg.type;

    LOCK(mtx_reprojected_positions);
    reprojected_positions.clear();
    UNLOCK(mtx_reprojected_positions);

    LOCK(mtx_reprojected_positions);
    for (const auto& point : obj_label_msg.reprojected_pos)
        {
            reprojected_positions.push_back(point);
        }
    UNLOCK(mtx_reprojected_positions);

    /* confirm obj_label is subscribed */
    LOCK(mtx_flag_obj_label);
    isReady_obj_label = true;
    UNLOCK(mtx_flag_obj_label);

    /* Publish fusion result if both of topics are ready */
   if (isReady_obj_label && isReady_cluster_centroids)
        {
            fusion_objects();

            LOCK(mtx_flag_obj_label);
            isReady_obj_label = false;
            UNLOCK(mtx_flag_obj_label);

            LOCK(mtx_flag_cluster_centroids);
            isReady_cluster_centroids = false;
            UNLOCK(mtx_flag_cluster_centroids);
        }

} /* void obj_label_cb() */

void cluster_centroids_cb(const lidar_tracker::centroids& cluster_centroids_msg)
{
    LOCK(mtx_centroids);
    centroids.clear();
    UNLOCK(mtx_centroids);

    LOCK(mtx_centroids);
    for (const auto& point : cluster_centroids_msg.points)
        {
            /* convert centroids coodinate from velodyne frame to map frame */
            tf::Vector3 pt(point.x, point.y, point.z);
            tf::Vector3 converted = transform * pt;

            geometry_msgs::Point point_in_map;
            point_in_map.x = converted.x();
            point_in_map.y = converted.y();
            point_in_map.z = converted.z();

            centroids.push_back(point_in_map);
        }
    UNLOCK(mtx_centroids);

    LOCK(mtx_flag_cluster_centroids);
    isReady_cluster_centroids = true;
    UNLOCK(mtx_flag_cluster_centroids);

    /* Publish fusion result if both of topics are ready */
    if (isReady_obj_label && isReady_cluster_centroids) {
        fusion_objects();

        LOCK(mtx_flag_obj_label);
        isReady_obj_label = false;
        UNLOCK(mtx_flag_obj_label);

        LOCK(mtx_flag_cluster_centroids);
        isReady_cluster_centroids = false;
        UNLOCK(mtx_flag_cluster_centroids);
    }

} /* void cluster_centroids_cb() */

int main(int argc, char* argv[])
{
    /* ROS initialization */
    ros::init(argc, argv, "obj_fusion");

    ros::NodeHandle n;

    /* Initialize flags */
    isReady_obj_label         = false;
    isReady_cluster_centroids = false;

    ros::Subscriber obj_label_sub         = n.subscribe("obj_label", SUBSCRIBE_QUEUE_SIZE, obj_label_cb);
    ros::Subscriber cluster_centroids_sub = n.subscribe("/cluster_centroids", SUBSCRIBE_QUEUE_SIZE, cluster_centroids_cb);
    obj_pose_pub = n.advertise<visualization_msgs::MarkerArray>("obj_pose", ADVERTISE_QUEUE_SIZE, ADVERTISE_LATCH);

    tf::TransformListener trf_listener;

    while (n.ok())
        {
            try {
                trf_listener.lookupTransform("map", "velodyne", ros::Time(0), transform);
            }
            catch (tf::TransformException ex) {
                ROS_INFO("%s", ex.what());
                ros::Duration(1.0).sleep();
            }

            ros::spinOnce();
        }

    return 0;
}
<commit_msg>Add timestamp topic to obj_fusion<commit_after>#include <ros/ros.h>
#include <cv_tracker/obj_label.h>
#include <lidar_tracker/centroids.h>
#include <visualization_msgs/Marker.h>
#include <visualization_msgs/MarkerArray.h>
#include <geometry_msgs/Point.h>
#include <math.h>
#include <float.h>
#include <tf/tf.h>
#include <tf/transform_listener.h>
#include <mutex>
#include <std_msgs/Time.h>

/* flag for comfirming whether multiple topics are received */
static bool isReady_obj_label;
static bool isReady_cluster_centroids;

static constexpr uint32_t SUBSCRIBE_QUEUE_SIZE = 100;
static constexpr uint32_t ADVERTISE_QUEUE_SIZE = 10;
static constexpr bool ADVERTISE_LATCH = false;

ros::Publisher obj_pose_pub;
ros::Publisher obj_pose_timestamp_pub;

static std::vector<geometry_msgs::Point> reprojected_positions;
static std::string object_type;
static std::vector<geometry_msgs::Point> centroids;
static ros::Time obj_pose_timestamp;

static tf::StampedTransform transform;

/* mutex to handle objects from within multi thread safely */
std::mutex mtx_flag_obj_label;
std::mutex mtx_flag_cluster_centroids;
std::mutex mtx_reprojected_positions;
std::mutex mtx_centroids;
#define LOCK(mtx) (mtx).lock()
#define UNLOCK(mtx) (mtx).unlock()

static double euclid_distance(const geometry_msgs::Point pos1,
                              const geometry_msgs::Point pos2)
{
    return sqrt(pow(pos1.x - pos2.x, 2) +
                pow(pos1.y - pos2.y, 2) +
                pow(pos1.z - pos2.z, 2));

} /* static double distance() */

/* fusion reprojected position and pointcloud centroids */
static void fusion_objects(void)
{
    std::vector<geometry_msgs::Point> reprojected_positions_current;
    std::vector<geometry_msgs::Point> centroids_current;

    LOCK(mtx_reprojected_positions);
    copy(reprojected_positions.begin(), reprojected_positions.end(), back_inserter(reprojected_positions_current));
    UNLOCK(mtx_reprojected_positions);

    LOCK(mtx_centroids);
    copy(centroids.begin(), centroids.end(), back_inserter(centroids_current));
    UNLOCK(mtx_centroids);

    if (centroids_current.empty() || reprojected_positions_current.empty()) {
        return;
    }

    std::vector<unsigned int> obj_indices;
    for(const auto& reproj_pos : reprojected_positions_current)
        {
            unsigned int min_idx      = 0;
            double       min_distance = DBL_MAX;

            /* calculate each euclid distance between reprojected position and centroids */
            for (unsigned int i=0; i<centroids_current.size(); i++)
                {
                    double distance = euclid_distance(reproj_pos, centroids_current.at(i));

                    /* Nearest centroid correspond to this reprojected object */
                    if (distance < min_distance)
                        {
                            min_distance = distance;
                            min_idx      = i;
                        }
                }
            obj_indices.push_back(min_idx);
        }

    /* Publish marker with centroids coordinates */
    visualization_msgs::MarkerArray pub_msg;

    std_msgs::ColorRGBA color_red;
    color_red.r = 1.0f;
    color_red.g = 0.0f;
    color_red.b = 0.0f;
    color_red.a = 1.0f;

    std_msgs::ColorRGBA color_blue;
    color_blue.r = 0.0f;
    color_blue.g = 0.0f;
    color_blue.b = 1.0f;
    color_blue.a = 1.0f;

    std_msgs::ColorRGBA color_green;
    color_green.r = 0.0f;
    color_green.g = 1.0f;
    color_green.b = 0.0f;
    color_green.a = 1.0f;

    for (const auto& idx : obj_indices)
        {
            visualization_msgs::Marker marker;

            /*Set the frame ID */
            marker.header.frame_id = "map";

            /* Set the namespace and id for this marker */
            marker.ns = object_type;
            marker.id = idx;

            /* Set the marker type */
            marker.type = visualization_msgs::Marker::SPHERE;

            /* Set the pose of the marker */
            marker.pose.position = centroids_current.at(idx);
            marker.pose.orientation.x = 0.0;
            marker.pose.orientation.y = 0.0;
            marker.pose.orientation.y = 0.0;
            marker.pose.orientation.w = 0.0;

            /* Set the scale of the marker -- We assume object as 1.5m sphere */
            marker.scale.x = (double)1.5;
            marker.scale.y = (double)1.5;
            marker.scale.z = (double)1.5;

            /* Set the color */
            if (object_type == "car") {
                marker.color = color_blue;
            }
            else if (object_type == "person") {
                marker.color = color_green;
            }
            else {
                marker.color = color_red;
            }

            marker.lifetime = ros::Duration(0.3);

            pub_msg.markers.push_back(marker);
        }

        obj_pose_pub.publish(pub_msg);
        obj_pose_timestamp_pub.publish(obj_pose_timestamp);
}

void obj_label_cb(const cv_tracker::obj_label& obj_label_msg)
{
    object_type = obj_label_msg.type;
    obj_pose_timestamp = obj_label_msg.header.stamp;

    LOCK(mtx_reprojected_positions);
    reprojected_positions.clear();
    UNLOCK(mtx_reprojected_positions);

    LOCK(mtx_reprojected_positions);
    for (const auto& point : obj_label_msg.reprojected_pos)
        {
            reprojected_positions.push_back(point);
        }
    UNLOCK(mtx_reprojected_positions);

    /* confirm obj_label is subscribed */
    LOCK(mtx_flag_obj_label);
    isReady_obj_label = true;
    UNLOCK(mtx_flag_obj_label);

    /* Publish fusion result if both of topics are ready */
   if (isReady_obj_label && isReady_cluster_centroids)
        {
            fusion_objects();

            LOCK(mtx_flag_obj_label);
            isReady_obj_label = false;
            UNLOCK(mtx_flag_obj_label);

            LOCK(mtx_flag_cluster_centroids);
            isReady_cluster_centroids = false;
            UNLOCK(mtx_flag_cluster_centroids);
        }

} /* void obj_label_cb() */

void cluster_centroids_cb(const lidar_tracker::centroids& cluster_centroids_msg)
{
    LOCK(mtx_centroids);
    centroids.clear();
    UNLOCK(mtx_centroids);

    LOCK(mtx_centroids);
    for (const auto& point : cluster_centroids_msg.points)
        {
            /* convert centroids coodinate from velodyne frame to map frame */
            tf::Vector3 pt(point.x, point.y, point.z);
            tf::Vector3 converted = transform * pt;

            geometry_msgs::Point point_in_map;
            point_in_map.x = converted.x();
            point_in_map.y = converted.y();
            point_in_map.z = converted.z();

            centroids.push_back(point_in_map);
        }
    UNLOCK(mtx_centroids);

    LOCK(mtx_flag_cluster_centroids);
    isReady_cluster_centroids = true;
    UNLOCK(mtx_flag_cluster_centroids);

    /* Publish fusion result if both of topics are ready */
    if (isReady_obj_label && isReady_cluster_centroids) {
        fusion_objects();

        LOCK(mtx_flag_obj_label);
        isReady_obj_label = false;
        UNLOCK(mtx_flag_obj_label);

        LOCK(mtx_flag_cluster_centroids);
        isReady_cluster_centroids = false;
        UNLOCK(mtx_flag_cluster_centroids);
    }

} /* void cluster_centroids_cb() */

int main(int argc, char* argv[])
{
    /* ROS initialization */
    ros::init(argc, argv, "obj_fusion");

    ros::NodeHandle n;

    /* Initialize flags */
    isReady_obj_label         = false;
    isReady_cluster_centroids = false;

    ros::Subscriber obj_label_sub         = n.subscribe("obj_label", SUBSCRIBE_QUEUE_SIZE, obj_label_cb);
    ros::Subscriber cluster_centroids_sub = n.subscribe("/cluster_centroids", SUBSCRIBE_QUEUE_SIZE, cluster_centroids_cb);
    obj_pose_pub = n.advertise<visualization_msgs::MarkerArray>("obj_pose", ADVERTISE_QUEUE_SIZE, ADVERTISE_LATCH);
    obj_pose_timestamp_pub = n.advertise<std_msgs::Time>("obj_pose_timestamp", ADVERTISE_QUEUE_SIZE);

    tf::TransformListener trf_listener;

    while (n.ok())
        {
            try {
                trf_listener.lookupTransform("map", "velodyne", ros::Time(0), transform);
            }
            catch (tf::TransformException ex) {
                ROS_INFO("%s", ex.what());
                ros::Duration(1.0).sleep();
            }

            ros::spinOnce();
        }

    return 0;
}
<|endoftext|>


<commit_before>#ifndef UNICODE
#error This code is written for Unicode only.
#endif

#include <cstdio>
#include <windows.h>
#include <msiquery.h>

#include <dsetup.h>

#include "targetver.h"
#include "resource.h"

#define DLLEXPORT __declspec(dllexport)

#define VERSION_NUMBER L"38"
#define VERSION_NAME L"Jun2008"

#ifdef X64
#define PLATFORM L"x64"
#else
#define PLATFORM L"x86"
#endif

LPCWSTR FileTable[] =
{
	L"dsetup32.dll",
	L"dsetup.dll",
	L"dxdllreg_x86.cab",
	L"dxsetup.exe",
	L"dxupdate.cab",

	VERSION_NAME L"_d3dx9_" VERSION_NUMBER L"_" PLATFORM L".cab",
	VERSION_NAME L"_d3dx10_" VERSION_NUMBER L"_" PLATFORM L".cab",
	VERSION_NAME L"_X3DAudio_" VERSION_NUMBER L"_" PLATFORM L".cab",
	VERSION_NAME L"_XAudio_" VERSION_NUMBER L"_" PLATFORM L".cab"
};

//based on http://syedgakbar.wordpress.com/2007/11/07/embedding-dll-and-binary-files-in-the-executable-applications/
bool ExtractResource(const HINSTANCE hInstance, WORD resourceId, LPCWSTR outputFilename)
{
	HRSRC hResource = FindResource(hInstance, MAKEINTRESOURCE(resourceId), L"BINARY");
	if(hResource == NULL)
		return false;
	HGLOBAL hFileResource = LoadResource(hInstance, hResource);
	if(hFileResource == NULL)
		return false;

	void* lpFile = LockResource(hFileResource);
	if(lpFile == NULL)
		return false;
	DWORD resourceSize = SizeofResource(hInstance, hResource);
	if(resourceSize == 0)
		return false;

	//open and write the file
	HANDLE hFile = CreateFile(outputFilename, GENERIC_READ | GENERIC_WRITE, 0,
		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
	if(hFile == INVALID_HANDLE_VALUE)
		return false;

	HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, resourceSize, NULL );
	if(hFileMapping == NULL)
	{
		CloseHandle(hFile);
		return false;
	}

	void* baseAddress = MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, 0);
	if(baseAddress == NULL )
	{
		CloseHandle(hFileMapping);
		CloseHandle(hFile);
		return false;
	}

	CopyMemory(baseAddress, lpFile, resourceSize);

	BOOL unmapResult = UnmapViewOfFile(baseAddress);
	if(unmapResult == 0)
	{
		CloseHandle(hFileMapping);
		CloseHandle(hFile);
		return false;
	}

	CloseHandle(hFileMapping);
	CloseHandle(hFile);

	return true;
}

bool RunDXSetup(LPCWSTR extractPath)
{
	wchar_t oldCurrentDir[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, oldCurrentDir);
	SetCurrentDirectory(extractPath);

	STARTUPINFO startupInfo = {0};
	PROCESS_INFORMATION processInfo = {0};

	startupInfo.cb = sizeof(STARTUPINFO);
	//can't use a read-only string with CreateProcessW
	wchar_t commandLine[] = L"dxsetup.exe /silent";
	if(!CreateProcess(NULL, commandLine, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo))
	{
		SetCurrentDirectory(oldCurrentDir);
		return false;
	}

	WaitForSingleObject(processInfo.hProcess, INFINITE);

	CloseHandle(processInfo.hThread);
	CloseHandle(processInfo.hProcess);
	SetCurrentDirectory(oldCurrentDir);
	return true;
}

//From http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THIS ((HINSTANCE)&__ImageBase)

EXTERN_C DLLEXPORT UINT DXSetupAction(MSIHANDLE session)
{
	HINSTANCE hInstance = HINST_THIS;

	wchar_t tempDir[MAX_PATH];
	DWORD tempDirLength = MAX_PATH;
	UINT x = MsiGetPropertyW(session, L"CustomActionData", tempDir, &tempDirLength);

	wchar_t fileName[MAX_PATH];

	int fileCount = sizeof(FileTable) / sizeof(LPCWSTR);
	for(int f = 0; f < fileCount; ++f)
	{
		wcscpy_s(fileName, MAX_PATH, tempDir);
		wcscat_s(fileName, MAX_PATH, FileTable[f]);

		bool result = ExtractResource(hInstance, IDR_BASEVALUE + f, fileName);
		if(!result)
		{
			return E_FAIL;
		}
	}

	bool setupResult = RunDXSetup(tempDir);

	//Delete all the temp files regardless
	for(int f = 0; f < fileCount; ++f)
	{
		wcscpy_s(fileName, MAX_PATH, tempDir);
		wcscat_s(fileName, MAX_PATH, FileTable[f]);

		DeleteFile(fileName);
	}

	return setupResult ? S_OK : E_FAIL;
}
<commit_msg>SP1 patches to DXSetupAction.<commit_after>#ifndef UNICODE
#error This code is written for Unicode only.
#endif

#include <cstdio>
#include <windows.h>
#include <msiquery.h>

#include <dsetup.h>

#include "targetver.h"
#include "resource.h"

#define DLLEXPORT __declspec(dllexport)

#define VERSION_NUMBER L"38"
#define VERSION_NAME L"Jun2008"

#ifdef X64
#define PLATFORM L"x64"
#else
#define PLATFORM L"x86"
#endif

LPCWSTR FileTable[] =
{
	L"dsetup32.dll",
	L"dsetup.dll",
	L"dxdllreg_x86.cab",
	L"dxsetup.exe",
	L"dxupdate.cab",

	VERSION_NAME L"_d3dx9_" VERSION_NUMBER L"_" PLATFORM L".cab",
	VERSION_NAME L"_d3dx10_" VERSION_NUMBER L"_" PLATFORM L".cab",
	VERSION_NAME L"_X3DAudio_" PLATFORM L".cab",
	VERSION_NAME L"_XAudio_" PLATFORM L".cab"
};

//based on http://syedgakbar.wordpress.com/2007/11/07/embedding-dll-and-binary-files-in-the-executable-applications/
bool ExtractResource(const HINSTANCE hInstance, WORD resourceId, LPCWSTR outputFilename)
{
	HRSRC hResource = FindResource(hInstance, MAKEINTRESOURCE(resourceId), L"BINARY");
	if(hResource == NULL)
		return false;
	HGLOBAL hFileResource = LoadResource(hInstance, hResource);
	if(hFileResource == NULL)
		return false;

	void* lpFile = LockResource(hFileResource);
	if(lpFile == NULL)
		return false;
	DWORD resourceSize = SizeofResource(hInstance, hResource);
	if(resourceSize == 0)
		return false;

	//open and write the file
	HANDLE hFile = CreateFile(outputFilename, GENERIC_READ | GENERIC_WRITE, 0,
		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
	if(hFile == INVALID_HANDLE_VALUE)
		return false;

	HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, resourceSize, NULL );
	if(hFileMapping == NULL)
	{
		CloseHandle(hFile);
		return false;
	}

	void* baseAddress = MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, 0);
	if(baseAddress == NULL )
	{
		CloseHandle(hFileMapping);
		CloseHandle(hFile);
		return false;
	}

	CopyMemory(baseAddress, lpFile, resourceSize);

	BOOL unmapResult = UnmapViewOfFile(baseAddress);
	if(unmapResult == 0)
	{
		CloseHandle(hFileMapping);
		CloseHandle(hFile);
		return false;
	}

	CloseHandle(hFileMapping);
	CloseHandle(hFile);

	return true;
}

bool RunDXSetup(LPCWSTR extractPath)
{
	wchar_t oldCurrentDir[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, oldCurrentDir);
	SetCurrentDirectory(extractPath);

	STARTUPINFO startupInfo = {0};
	PROCESS_INFORMATION processInfo = {0};

	startupInfo.cb = sizeof(STARTUPINFO);
	//can't use a read-only string with CreateProcessW
	wchar_t commandLine[] = L"dxsetup.exe /silent";
	if(!CreateProcess(NULL, commandLine, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo))
	{
		SetCurrentDirectory(oldCurrentDir);
		return false;
	}

	WaitForSingleObject(processInfo.hProcess, INFINITE);

	CloseHandle(processInfo.hThread);
	CloseHandle(processInfo.hProcess);
	SetCurrentDirectory(oldCurrentDir);
	return true;
}

//From http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THIS ((HINSTANCE)&__ImageBase)

EXTERN_C DLLEXPORT UINT DXSetupAction(MSIHANDLE session)
{
	HINSTANCE hInstance = HINST_THIS;

	wchar_t tempDir[MAX_PATH];
	DWORD tempDirLength = MAX_PATH;
	UINT x = MsiGetPropertyW(session, L"CustomActionData", tempDir, &tempDirLength);

	wchar_t fileName[MAX_PATH];

	int fileCount = sizeof(FileTable) / sizeof(LPCWSTR);
	for(int f = 0; f < fileCount; ++f)
	{
		wcscpy_s(fileName, MAX_PATH, tempDir);
		wcscat_s(fileName, MAX_PATH, FileTable[f]);

		bool result = ExtractResource(hInstance, IDR_BASEVALUE + f, fileName);
		if(!result)
		{
			return E_FAIL;
		}
	}

	bool setupResult = RunDXSetup(tempDir);

	//Delete all the temp files regardless
	for(int f = 0; f < fileCount; ++f)
	{
		wcscpy_s(fileName, MAX_PATH, tempDir);
		wcscat_s(fileName, MAX_PATH, FileTable[f]);

		DeleteFile(fileName);
	}

	return setupResult ? S_OK : E_FAIL;
}
<|endoftext|>


<commit_before>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#include "util.h"

#ifdef _WIN32
#include <windows.h>
#endif

#include <GL/glew.h>

#include <stdio.h>
#include <stdarg.h>

namespace gl = virvo::gl;

#ifndef APIENTRY
#define APIENTRY
#endif

#ifndef NDEBUG

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
#if defined(GL_KHR_debug)
static char const* GetDebugTypeString(GLenum type)
{
    switch (type)
    {
    case GL_DEBUG_TYPE_ERROR:
        return "error";
    case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
        return "deprecated behavior detected";
    case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
        return "undefined behavior detected";
    case GL_DEBUG_TYPE_PORTABILITY:
        return "portablility warning";
    case GL_DEBUG_TYPE_PERFORMANCE:
        return "performance warning";
    case GL_DEBUG_TYPE_OTHER:
        return "other";
    case GL_DEBUG_TYPE_MARKER:
        return "marker";
    }

    return "{unknown type}";
}
#endif

#if defined(GL_KHR_debug)
//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
#ifdef _WIN32
static void OutputDebugStringAF(char const* format, ...)
{
    char text[1024] = {0};

    va_list args;
    va_start(args, format);

    _vsnprintf_s(text, _TRUNCATE, format, args);

    va_end(args);

    OutputDebugStringA(text);
}
#endif

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
static void APIENTRY DebugCallback( GLenum /*source*/,
                                    GLenum type,
                                    GLuint /*id*/,
                                    GLenum /*severity*/,
                                    GLsizei /*length*/,
                                    const GLchar* message,
                                    GLvoid* /*userParam*/
                                    )
{
    if (type != GL_DEBUG_TYPE_ERROR)
        return;

#ifdef _WIN32
    if (IsDebuggerPresent())
    {
        OutputDebugStringAF("GL %s: %s\n", GetDebugTypeString(type), message);
        DebugBreak();
    }
#endif

    fprintf(stderr, "GL %s: %s\n", GetDebugTypeString(type), message);
}
#endif

#endif // !NDEBUG

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
void gl::enableDebugCallback()
{
#if !defined(NDEBUG) && defined(GL_KHR_debug)
    if (GLEW_KHR_debug)
    {
        glEnable(GL_DEBUG_OUTPUT);
        glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);

        glDebugMessageCallback(DebugCallback, 0);
    }
#endif // !NDEBUG
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
GLenum gl::getError(char const* file, int line)
{
    GLenum err = glGetError();

    if (err != GL_NO_ERROR)
        fprintf(stderr, "%s(%d) : GL error: %s\n", file, line, gluErrorString(err));

    return err;
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
static char const* GetFramebufferStatusString(GLenum status)
{
    switch (status)
    {
    case GL_FRAMEBUFFER_COMPLETE:
        return "framebuffer complete";
    case GL_FRAMEBUFFER_UNDEFINED:
        return "framebuffer undefined";
    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
        return "framebuffer incomplete attachment";
    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
        return "framebuffer incomplete missing attachment";
    case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
        return "framebuffer incomplete draw buffer";
    case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
        return "framebuffer incomplete read buffer";
    case GL_FRAMEBUFFER_UNSUPPORTED:
        return "framebuffer unsupported";
    case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
        return "framebuffer incomplete multisample";
#ifdef GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS
    case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
        return "framebuffer incomplete layer targets";
#endif
    default:
        return "{unknown status}";
    }
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
GLenum gl::getFramebufferStatus(GLenum target, char const* file, int line)
{
    GLenum status = glCheckFramebufferStatus(target);

    if (status != GL_FRAMEBUFFER_COMPLETE)
        fprintf(stderr, "%s(%d) : GL framebuffer error: %s\n", file, line, GetFramebufferStatusString(status));

    return status;
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
static void DrawFullScreenQuad()
{
    GLint matrixMode = 0;

    glGetIntegerv(GL_MATRIX_MODE, &matrixMode);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
    glEnd();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glMatrixMode(matrixMode);
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
void gl::blendTexture(GLuint texture, GLenum sfactor, GLenum dfactor)
{
    glPushAttrib(GL_ALL_ATTRIB_BITS);

    glActiveTexture(GL_TEXTURE0);

    glEnable(GL_BLEND);
    glBlendFunc(sfactor, dfactor);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);

    glDepthMask(GL_FALSE);

    DrawFullScreenQuad();

    glPopAttrib();
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
void gl::blendTexture(GLuint texture)
{
    blendTexture(texture, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
void gl::blendPixels(GLsizei srcW, GLsizei srcH, GLenum format, GLenum type, const GLvoid* pixels, GLenum sfactor, GLenum dfactor)
{
    glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_PIXEL_MODE_BIT);

    GLint viewport[4];

    glGetIntegerv(GL_VIEWPORT, &viewport[0]);

    glWindowPos2i(viewport[0], viewport[1]);

    GLfloat scaleX = static_cast<GLfloat>(viewport[2]) / srcW;
    GLfloat scaleY = static_cast<GLfloat>(viewport[3]) / srcH;

    glPixelZoom(scaleX, scaleY);

    glEnable(GL_BLEND);
    glBlendFunc(sfactor, dfactor);

    glDrawPixels(srcW, srcH, format, type, pixels);

    glPopAttrib();
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
void gl::blendPixels(GLsizei srcW, GLsizei srcH, GLenum format, GLenum type, const GLvoid* pixels)
{
    blendPixels(srcW, srcH, format, type, pixels, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
void gl::renderInterlacedStereoStencilBuffer(bool lines)
{
    static const GLubyte kPatternLines[32*(32/8)] = {
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
    };

    static const GLubyte kPatternCheckerBoard[32*(32/8)] = {
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
    };

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_SCISSOR_TEST);
    glDisable(GL_LIGHTING);

    glColorMask(0, 0, 0, 0);
    glDepthMask(0);

    glClearStencil(0);
    glClear(GL_STENCIL_BUFFER_BIT);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glEnable(GL_POLYGON_STIPPLE);
    if (lines)
        glPolygonStipple(kPatternLines);
    else
        glPolygonStipple(kPatternCheckerBoard);

    glEnable(GL_STENCIL_TEST);
    glStencilMask(0xFFFFFFFF);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);

    DrawFullScreenQuad();

    glPopAttrib();
    glPopClientAttrib();
}
<commit_msg>Remove support to print error messages to the VS debug window<commit_after>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#include "util.h"

#ifdef _WIN32
#include <windows.h>
#endif

#include <GL/glew.h>

#include <stdio.h>
#include <stdarg.h>

namespace gl = virvo::gl;

#ifndef APIENTRY
#define APIENTRY
#endif

#if !defined(NDEBUG) && defined(GL_KHR_debug)

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
static char const* GetDebugTypeString(GLenum type)
{
    switch (type)
    {
    case GL_DEBUG_TYPE_ERROR:
        return "error";
    case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
        return "deprecated behavior detected";
    case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
        return "undefined behavior detected";
    case GL_DEBUG_TYPE_PORTABILITY:
        return "portablility warning";
    case GL_DEBUG_TYPE_PERFORMANCE:
        return "performance warning";
    case GL_DEBUG_TYPE_OTHER:
        return "other";
    case GL_DEBUG_TYPE_MARKER:
        return "marker";
    }

    return "{unknown type}";
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
static void APIENTRY DebugCallback( GLenum /*source*/,
                                    GLenum type,
                                    GLuint /*id*/,
                                    GLenum /*severity*/,
                                    GLsizei /*length*/,
                                    const GLchar* message,
                                    GLvoid* /*userParam*/
                                    )
{
    fprintf(stderr, "GL %s: %s\n", GetDebugTypeString(type), message);

    if (type == GL_DEBUG_TYPE_ERROR)
    {
#ifdef _WIN32
        if (IsDebuggerPresent())
            DebugBreak();
#endif
    }
}

#endif // !NDEBUG && GL_KHR_debug

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
void gl::enableDebugCallback()
{
#if !defined(NDEBUG) && defined(GL_KHR_debug)
    if (GLEW_KHR_debug)
    {
        glEnable(GL_DEBUG_OUTPUT);
        glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);

        glDebugMessageCallback(DebugCallback, 0);
    }
#endif
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
GLenum gl::getError(char const* file, int line)
{
    GLenum err = glGetError();

    if (err != GL_NO_ERROR)
        fprintf(stderr, "%s(%d) : GL error: %s\n", file, line, gluErrorString(err));

    return err;
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
static char const* GetFramebufferStatusString(GLenum status)
{
    switch (status)
    {
    case GL_FRAMEBUFFER_COMPLETE:
        return "framebuffer complete";
    case GL_FRAMEBUFFER_UNDEFINED:
        return "framebuffer undefined";
    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
        return "framebuffer incomplete attachment";
    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
        return "framebuffer incomplete missing attachment";
    case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
        return "framebuffer incomplete draw buffer";
    case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
        return "framebuffer incomplete read buffer";
    case GL_FRAMEBUFFER_UNSUPPORTED:
        return "framebuffer unsupported";
    case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
        return "framebuffer incomplete multisample";
#ifdef GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS
    case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
        return "framebuffer incomplete layer targets";
#endif
    default:
        return "{unknown status}";
    }
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
GLenum gl::getFramebufferStatus(GLenum target, char const* file, int line)
{
    GLenum status = glCheckFramebufferStatus(target);

    if (status != GL_FRAMEBUFFER_COMPLETE)
        fprintf(stderr, "%s(%d) : GL framebuffer error: %s\n", file, line, GetFramebufferStatusString(status));

    return status;
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
static void DrawFullScreenQuad()
{
    GLint matrixMode = 0;

    glGetIntegerv(GL_MATRIX_MODE, &matrixMode);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f,  1.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f,  1.0f);
    glEnd();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glMatrixMode(matrixMode);
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
void gl::blendTexture(GLuint texture, GLenum sfactor, GLenum dfactor)
{
    glPushAttrib(GL_ALL_ATTRIB_BITS);

    glActiveTexture(GL_TEXTURE0);

    glEnable(GL_BLEND);
    glBlendFunc(sfactor, dfactor);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);

    glDepthMask(GL_FALSE);

    DrawFullScreenQuad();

    glPopAttrib();
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
void gl::blendTexture(GLuint texture)
{
    blendTexture(texture, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
void gl::blendPixels(GLsizei srcW, GLsizei srcH, GLenum format, GLenum type, const GLvoid* pixels, GLenum sfactor, GLenum dfactor)
{
    glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_PIXEL_MODE_BIT);

    GLint viewport[4];

    glGetIntegerv(GL_VIEWPORT, &viewport[0]);

    glWindowPos2i(viewport[0], viewport[1]);

    GLfloat scaleX = static_cast<GLfloat>(viewport[2]) / srcW;
    GLfloat scaleY = static_cast<GLfloat>(viewport[3]) / srcH;

    glPixelZoom(scaleX, scaleY);

    glEnable(GL_BLEND);
    glBlendFunc(sfactor, dfactor);

    glDrawPixels(srcW, srcH, format, type, pixels);

    glPopAttrib();
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
void gl::blendPixels(GLsizei srcW, GLsizei srcH, GLenum format, GLenum type, const GLvoid* pixels)
{
    blendPixels(srcW, srcH, format, type, pixels, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}

//--------------------------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------------------------
void gl::renderInterlacedStereoStencilBuffer(bool lines)
{
    static const GLubyte kPatternLines[32*(32/8)] = {
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
    };

    static const GLubyte kPatternCheckerBoard[32*(32/8)] = {
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
        0xAA, 0xAA, 0xAA, 0xAA,
        0x55, 0x55, 0x55, 0x55,
    };

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_SCISSOR_TEST);
    glDisable(GL_LIGHTING);

    glColorMask(0, 0, 0, 0);
    glDepthMask(0);

    glClearStencil(0);
    glClear(GL_STENCIL_BUFFER_BIT);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glEnable(GL_POLYGON_STIPPLE);
    if (lines)
        glPolygonStipple(kPatternLines);
    else
        glPolygonStipple(kPatternCheckerBoard);

    glEnable(GL_STENCIL_TEST);
    glStencilMask(0xFFFFFFFF);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);

    DrawFullScreenQuad();

    glPopAttrib();
    glPopClientAttrib();
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/customize/p9_xip_customize.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef _P9_XIP_CUSTOMIZE_
#define _P9_XIP_CUSTOMIZE_

#include <fapi2.H>

typedef fapi2::ReturnCode (*p9_xip_customize_FP_t) (
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_proc_target,
    void*     io_image,
    uint32_t& io_imageSize,
    void*     io_ringSectionBuf,
    uint32_t& io_ringSectionBufSize,
    uint8_t   i_sysPhase,
    uint8_t   i_modeBuild,
    void*     io_ringBuf1,
    uint32_t  i_ringBufSize1,
    void*     io_ringBuf2,
    uint32_t  i_ringBufSize2,
    uint32_t& io_bootCoreMask);

extern "C"
{
/// @brief p9_xip_customize used to customize the SBE/CME/SGPE images with
///        mailbox attributes, VPD rings and other stuff.
///
/// @param[in] i_proc_target             => P9 proc chip target
/// @param[in/out] io_image              => Pointer to an in-memory image
///                                         HB_SBE:
///                                             In:  SBE image
///                                             Out: Seeprom image
///                                         RT_{CME,SGPE}:
///                                             In:  HW image
///                                             Out: HW image
/// @param[in/out] io_imageSize          => Size of image
///                                         HB_SBE:
///                                             In:  MAX_SEEPROM_IMAGE_SIZE
///                                             Out: Final size
///                                         RT_{CME,SGPE}:
///                                             In:  Size of HW image
///                                             Out: Unchanged
/// @param[in/out] io_ringSectionBuf     => Pointer to an in-memory ring section
///                                         buffer
///                                         HB_SBE:
///                                             Used as temporary image work buffer
///                                             In:  Undefined
///                                             Out: Undefined
///                                         RT_{CME,SGPE}:
///                                             In:  Undefined
///                                             Out: Updated .rings section
/// @param[in/out] io_ringSectionBufSize => In: Size of ring section buffer
///                                         HB_SBE:
///                                             In:  MAX_SEEPROM_IMAGE_SIZE
///                                             Out: Unchanged
///                                         RT_{CME,SGPE}:
///                                             In:  MAX_RT_IMAGE_SIZE
///                                             Out: Final size
/// @param[in] i_sysPhase                => ={HB_SBE, RT_CME, RT_SGPE}
/// @param[in] i_modeBuild               => ={IPL, REBUILD}
/// @param[in/out] io_ringBuf1           => Caller supplied in-memory buffer
///                                         for uncompressed VPD rings in
/// @param[in] i_ringBufSize1            => Max size of VPD ring buffer
///                                         (Should equal MAX_RING_BUF_SIZE)
/// @param[in/out] io_ringBuf2           => Caller supplied in-memory buffer
///                                         for uncompressed overlay rings
/// @param[in] i_ringBufSize2            => Max size of overlay ring buffer
///                                         (Should equal MAX_RING_BUF_SIZE)
/// @param[in/out] io_bootCoreMask       => In: Mask of the desired boot cores
///                                         Out: Actual boot cores
///                                         (Only used in HB_SBE sysPhase)
///                                         (Bits(8:31) = EC00:EC23)
///
/// @return FAPI_RC_SUCCESS if the customization was successful
///
    fapi2::ReturnCode p9_xip_customize (
        const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_proc_target,
        void*     io_image,
        uint32_t& io_imageSize,
        void*     io_ringSectionBuf,
        uint32_t& io_ringSectionBufSize,
        uint8_t   i_sysPhase,
        uint8_t   i_modeBuild,
        void*     io_ringBuf1,
        uint32_t  i_ringBufSize1,
        void*     io_ringBuf2,
        uint32_t  i_ringBufSize2,
        uint32_t& io_bootCoreMask);

}
#endif
<commit_msg>xip_customize: Added CME/SGPE support.<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/customize/p9_xip_customize.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef _P9_XIP_CUSTOMIZE_
#define _P9_XIP_CUSTOMIZE_

#include <fapi2.H>

typedef fapi2::ReturnCode (*p9_xip_customize_FP_t) (
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_proc_target,
    void*     io_image,
    uint32_t& io_imageSize,
    void*     io_ringSectionBuf,
    uint32_t& io_ringSectionBufSize,
    uint8_t   i_sysPhase,
    uint8_t   i_modeBuild,
    void*     io_ringBuf1,
    uint32_t  i_ringBufSize1,
    void*     io_ringBuf2,
    uint32_t  i_ringBufSize2,
    uint32_t& io_bootCoreMask);

extern "C"
{
/// @brief p9_xip_customize used to customize the SBE/CME/SGPE images with
///        mailbox attributes, VPD rings and other stuff.
///
/// @param[in] i_proc_target             => P9 proc chip target
/// @param[in/out] io_image              => Pointer to an in-memory image
///                                         HB_SBE:
///                                             In:  SBE image
///                                             Out: Seeprom image
///                                         RT_{CME,SGPE}:
///                                             In:  HW image
///                                             Out: HW image
/// @param[in/out] io_imageSize          => Size of image
///                                         HB_SBE:
///                                             In:  MAX_SEEPROM_IMAGE_SIZE
///                                             Out: Final size
///                                         RT_{CME,SGPE}:
///                                             In:  Size of HW image
///                                             Out: Unchanged
/// @param[in/out] io_ringSectionBuf     => Pointer to an in-memory ring section
///                                         buffer
///                                         HB_SBE:
///                                             Used as temporary image work buffer
///                                             In:  Undefined
///                                             Out: Undefined
///                                         RT_{CME,SGPE}:
///                                             In:  Undefined
///                                             Out: Updated .rings section
/// @param[in/out] io_ringSectionBufSize => In: Size of ring section buffer
///                                         HB_SBE:
///                                             In:  MAX_SEEPROM_IMAGE_SIZE
///                                             Out: Unchanged
///                                         RT_{CME,SGPE}:
///                                             In:  MAX_SEEPROM_IMAGE_SIZE
///                                             Out: Final size
/// @param[in] i_sysPhase                => ={HB_SBE, RT_CME, RT_SGPE}
/// @param[in] i_modeBuild               => ={IPL, REBUILD}
/// @param[in/out] io_ringBuf1           => Caller supplied in-memory buffer
///                                         for uncompressed VPD rings in
/// @param[in] i_ringBufSize1            => Max size of VPD ring buffer
///                                         (Should equal MAX_RING_BUF_SIZE)
/// @param[in/out] io_ringBuf2           => Caller supplied in-memory buffer
///                                         for uncompressed overlay rings
/// @param[in] i_ringBufSize2            => Max size of overlay ring buffer
///                                         (Should equal MAX_RING_BUF_SIZE)
/// @param[in/out] io_bootCoreMask       => In: Mask of the desired boot cores
///                                         Out: Actual boot cores
///                                         (Only used in HB_SBE sysPhase)
///                                         (Bits(8:31) = EC00:EC23)
///
/// @return FAPI_RC_SUCCESS if the customization was successful
///
    fapi2::ReturnCode p9_xip_customize (
        const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_proc_target,
        void*     io_image,
        uint32_t& io_imageSize,
        void*     io_ringSectionBuf,
        uint32_t& io_ringSectionBufSize,
        uint8_t   i_sysPhase,
        uint8_t   i_modeBuild,
        void*     io_ringBuf1,
        uint32_t  i_ringBufSize1,
        void*     io_ringBuf2,
        uint32_t  i_ringBufSize2,
        uint32_t& io_bootCoreMask);

}
#endif
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs01.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file mrs01.C
/// @brief Run and manage the DDR4 MRS01 loading
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>

#include <mss.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_DIMM;

using fapi2::FAPI2_RC_SUCCESS;

namespace mss
{

namespace ddr4
{

///
/// @brief mrs01_data ctor
/// @param[in] a fapi2::TARGET_TYPE_DIMM target
/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
mrs01_data::mrs01_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
    iv_dll_enable(fapi2::ENUM_ATTR_EFF_DRAM_DLL_ENABLE_YES),
    iv_additive_latency(0),
    iv_wl_enable(0),
    iv_tdqs(0),
    iv_qoff(0)
{
    FAPI_TRY( mss::eff_dram_dll_enable(i_target, iv_dll_enable) );
    FAPI_TRY( mss::vpd_mt_dram_drv_imp_dq_dqs(i_target, &(iv_odic[0])) );
    FAPI_TRY( mss::eff_dram_al(i_target, iv_additive_latency) );
    FAPI_TRY( mss::eff_dram_wr_lvl_enable(i_target, iv_wl_enable) );
    FAPI_TRY( mss::vpd_mt_dram_rtt_nom(i_target, &(iv_rtt_nom[0])) );
    FAPI_TRY( mss::eff_dram_tdqs(i_target, iv_tdqs) );
    FAPI_TRY( mss::eff_dram_output_buffer(i_target, iv_qoff) );

    o_rc = fapi2::FAPI2_RC_SUCCESS;
    return;

fapi_try_exit:
    o_rc = fapi2::current_err;
    FAPI_ERR("unable to get attributes for mrs0");
    return;
}

///
/// @brief Configure the ARR0 of the CCS instruction for mrs01
/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
/// @param[in,out] io_inst the instruction to fixup
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs01(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
                        ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
                        const uint64_t i_rank)
{
    // Check to make sure our ctor worked ok
    mrs01_data l_data( i_target, fapi2::current_err );
    FAPI_TRY( fapi2::current_err, "Unable to construct MRS01 data from attributes");
    FAPI_TRY( mrs01(i_target, l_data, io_inst, i_rank) );

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Configure the ARR0 of the CCS instruction for mrs01, data object as input
/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
/// @param[in] i_data an mrs01_data object, filled in
/// @param[in,out] io_inst the instruction to fixup
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs01(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                        const mrs01_data& i_data,
                        ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
                        const uint64_t i_rank)
{
    // Little table to map Output Driver Imepdance Control. 34Ohm is index 0,
    // 48Ohm is index 1
    // Left bit is A2, right bit is A1
    constexpr uint8_t odic_map[2] = { 0b00, 0b01 };

    // Indexed by denominator. So, if RQZ is 240, and you have OHM240, then you're looking
    // for index 1. So this doesn't correspond directly with the table in the JEDEC spec,
    // as that's not in "denominator order."
    //                                   0  RQZ/1  RQZ/2  RQZ/3  RQZ/4  RQZ/5  RQZ/6  RQZ/7
    constexpr uint8_t rtt_nom_map[8] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };

    size_t l_rtt_nom_index = 0;

    fapi2::buffer<uint8_t> l_additive_latency;
    fapi2::buffer<uint8_t> l_odic_buffer;
    fapi2::buffer<uint8_t> l_rtt_nom_buffer;

    FAPI_ASSERT( ((i_data.iv_odic[mss::index(i_rank)] == fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM34) ||
                  (i_data.iv_odic[mss::index(i_rank)] == fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM48)),
                 fapi2::MSS_BAD_MR_PARAMETER()
                 .set_MR_NUMBER(1)
                 .set_PARAMETER(OUTPUT_IMPEDANCE)
                 .set_PARAMETER_VALUE(i_data.iv_odic[mss::index(i_rank)])
                 .set_DIMM_IN_ERROR(i_target),
                 "Bad value for output driver impedance: %d (%s)", i_data.iv_odic[mss::index(i_rank)], mss::c_str(i_target));

    // Map from impedance to bits in MRS1
    l_odic_buffer = (i_data.iv_odic[mss::index(i_rank)] == fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM34) ?
                    odic_map[0] : odic_map[1];

    // We have to be careful about 0
    l_rtt_nom_index = (i_data.iv_rtt_nom[mss::index(i_rank)] == 0) ?
                      0 : fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_RTT_NOM_OHM240 / i_data.iv_rtt_nom[mss::index(i_rank)];

    // Map from RTT_NOM array to the value in the map
    l_rtt_nom_buffer = rtt_nom_map[l_rtt_nom_index];

    // Print this here as opposed to the MRS01 ctor as we want to see the specific rtt now information
    FAPI_INF("MR1 rank %d attributes: DLL_ENABLE: 0x%x, ODIC: 0x%x(0x%x), AL: 0x%x, WLE: 0x%x, "
             "RTT_NOM: 0x%x(0x%x), TDQS: 0x%x, QOFF: 0x%x", i_rank,
             i_data.iv_dll_enable, i_data.iv_odic[mss::index(i_rank)], uint8_t(l_odic_buffer), uint8_t(l_additive_latency),
             i_data.iv_wl_enable,
             i_data.iv_rtt_nom[mss::index(i_rank)], uint8_t(l_rtt_nom_buffer), i_data.iv_tdqs, i_data.iv_qoff);

    io_inst.arr0.writeBit<A0>(i_data.iv_dll_enable);
    mss::swizzle<A1, 2, 7>(l_odic_buffer, io_inst.arr0);
    mss::swizzle<A3, 2, 7>(fapi2::buffer<uint8_t>(i_data.iv_additive_latency), io_inst.arr0);
    io_inst.arr0.writeBit<A7>(i_data.iv_wl_enable);
    mss::swizzle<A8, 3, 7>(l_rtt_nom_buffer, io_inst.arr0);
    io_inst.arr0.writeBit<A11>(i_data.iv_tdqs);
    io_inst.arr0.writeBit<A12>(i_data.iv_qoff);

    FAPI_INF("MR1: 0x%016llx", uint64_t(io_inst.arr0));

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Helper function for mrs01_decode
/// @param[in] i_inst the CCS instruction
/// @param[in] i_rank ths rank in question
/// @param[out] o_dll_enable the dll enable bit
/// @param[out] o_wrl_enable the write leveling enable bit
/// @param[out] o_tdqs the tdqs enable bit
/// @param[out] o_qoff the qoff bit
/// @param[out] o_odic the output driver impedance control setting
/// @param[out] o_additive_latency the additive latency setting
/// @param[out] o_rtt_nom the rtt_nom setting
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode mrs01_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
                                      const uint64_t i_rank,
                                      uint8_t& o_dll_enable,
                                      uint8_t& o_wrl_enable,
                                      uint8_t& o_tdqs,
                                      uint8_t& o_qoff,
                                      fapi2::buffer<uint8_t>& o_odic,
                                      fapi2::buffer<uint8_t>& o_additive_latency,
                                      fapi2::buffer<uint8_t>& o_rtt_nom)
{
    o_odic = 0;
    o_additive_latency = 0;
    o_rtt_nom = 0;

    o_dll_enable = i_inst.arr0.getBit<A0>();
    o_wrl_enable = i_inst.arr0.getBit<A7>();
    o_tdqs = i_inst.arr0.getBit<A11>();
    o_qoff = i_inst.arr0.getBit<A12>();

    mss::swizzle<6, 2, A2>(i_inst.arr0, o_odic);
    mss::swizzle<6, 2, A4>(i_inst.arr0, o_additive_latency);
    mss::swizzle<5, 3, A10>(i_inst.arr0, o_rtt_nom);

    FAPI_INF("MR1 rank %d decode: DLL_ENABLE: 0x%x, ODIC: 0x%x, AL: 0x%x, WLE: 0x%x, "
             "RTT_NOM: 0x%x, TDQS: 0x%x, QOFF: 0x%x", i_rank,
             o_dll_enable, uint8_t(o_odic), uint8_t(o_additive_latency), o_wrl_enable, uint8_t(o_rtt_nom),
             o_tdqs, o_qoff);

    return FAPI2_RC_SUCCESS;
}

///
/// @brief Given a CCS instruction which contains address bits with an encoded MRS1,
/// decode and trace the contents
/// @param[in] i_inst the CCS instruction
/// @param[in] i_rank ths rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode mrs01_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
                               const uint64_t i_rank)
{
    uint8_t l_dll_enable = 0;
    uint8_t l_wrl_enable = 0;
    uint8_t l_tdqs = 0;
    uint8_t l_qoff = 0;
    fapi2::buffer<uint8_t> l_odic;
    fapi2::buffer<uint8_t> l_additive_latency;
    fapi2::buffer<uint8_t> l_rtt_nom;

    return mrs01_decode_helper(i_inst, i_rank, l_dll_enable, l_wrl_enable, l_tdqs, l_qoff, l_odic,
                               l_additive_latency, l_rtt_nom);
}

fapi2::ReturnCode (*mrs01_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
        const mrs01_data& i_data,
        ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
        const uint64_t i_rank) = &mrs01;

fapi2::ReturnCode (*mrs01_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
                                        const uint64_t i_rank) = &mrs01_decode;

} // ns ddr4

} // ns mss
<commit_msg>Move MRS attributes to eff_config to calc LRDIMMs<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs01.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file mrs01.C
/// @brief Run and manage the DDR4 MRS01 loading
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>

#include <mss.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_DIMM;

using fapi2::FAPI2_RC_SUCCESS;

namespace mss
{

namespace ddr4
{

///
/// @brief mrs01_data ctor
/// @param[in] a fapi2::TARGET_TYPE_DIMM target
/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
mrs01_data::mrs01_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
    iv_dll_enable(fapi2::ENUM_ATTR_EFF_DRAM_DLL_ENABLE_YES),
    iv_additive_latency(0),
    iv_wl_enable(0),
    iv_tdqs(0),
    iv_qoff(0)
{
    FAPI_TRY( mss::eff_dram_dll_enable(i_target, iv_dll_enable) );
    FAPI_TRY( mss::vpd_mt_dram_drv_imp_dq_dqs(i_target, &(iv_odic[0])) );
    FAPI_TRY( mss::eff_dram_al(i_target, iv_additive_latency) );
    FAPI_TRY( mss::eff_dram_wr_lvl_enable(i_target, iv_wl_enable) );
    FAPI_TRY( mss::eff_dram_rtt_nom(i_target, &(iv_rtt_nom[0])) );
    FAPI_TRY( mss::eff_dram_tdqs(i_target, iv_tdqs) );
    FAPI_TRY( mss::eff_dram_output_buffer(i_target, iv_qoff) );

    o_rc = fapi2::FAPI2_RC_SUCCESS;
    return;

fapi_try_exit:
    o_rc = fapi2::current_err;
    FAPI_ERR("unable to get attributes for mrs0");
    return;
}

///
/// @brief Configure the ARR0 of the CCS instruction for mrs01
/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
/// @param[in,out] io_inst the instruction to fixup
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs01(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
                        ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
                        const uint64_t i_rank)
{
    // Check to make sure our ctor worked ok
    mrs01_data l_data( i_target, fapi2::current_err );
    FAPI_TRY( fapi2::current_err, "Unable to construct MRS01 data from attributes");
    FAPI_TRY( mrs01(i_target, l_data, io_inst, i_rank) );

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Configure the ARR0 of the CCS instruction for mrs01, data object as input
/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
/// @param[in] i_data an mrs01_data object, filled in
/// @param[in,out] io_inst the instruction to fixup
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs01(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                        const mrs01_data& i_data,
                        ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
                        const uint64_t i_rank)
{
    // Little table to map Output Driver Imepdance Control. 34Ohm is index 0,
    // 48Ohm is index 1
    // Left bit is A2, right bit is A1
    constexpr uint8_t odic_map[] = { 0b00, 0b01 };

    constexpr uint64_t ODIC_LENGTH = 2;
    constexpr uint64_t ODIC_START_BIT = 7;
    constexpr uint64_t ADDITIVE_LATENCE_LENGTH = 2;
    constexpr uint64_t ADDITIVE_LATENCE_START_BIT = 7;
    constexpr uint64_t RTT_NOM_LENGTH = 3;
    constexpr uint64_t RTT_NOM_START_BIT = 7;

    fapi2::buffer<uint8_t> l_additive_latency;
    fapi2::buffer<uint8_t> l_odic_buffer;
    fapi2::buffer<uint8_t> l_rtt_nom_buffer;

    //check here to make sure the rank indexes correctly into the attribute array
    //It's equivalent to mss::index(i_rank) < l_rtt_nom.size() if C arrays had a .size() method
    fapi2::Assert( mss::index(i_rank) < MAX_RANK_PER_DIMM);

    FAPI_ASSERT( ((i_data.iv_odic[mss::index(i_rank)] == fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM34) ||
                  (i_data.iv_odic[mss::index(i_rank)] == fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM48)),
                 fapi2::MSS_BAD_MR_PARAMETER()
                 .set_MR_NUMBER(1)
                 .set_PARAMETER(OUTPUT_IMPEDANCE)
                 .set_PARAMETER_VALUE(i_data.iv_odic[mss::index(i_rank)])
                 .set_DIMM_IN_ERROR(i_target),
                 "Bad value for output driver impedance: %d (%s)", i_data.iv_odic[mss::index(i_rank)], mss::c_str(i_target));

    // Map from impedance to bits in MRS1
    l_odic_buffer = (i_data.iv_odic[mss::index(i_rank)] == fapi2::ENUM_ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS_OHM34) ?
                    odic_map[0] : odic_map[1];

    // Map from RTT_NOM array to the value in the map
    l_rtt_nom_buffer = i_data.iv_rtt_nom[mss::index(i_rank)];

    // Print this here as opposed to the MRS01 ctor as we want to see the specific rtt now information
    FAPI_INF("MR1 rank %d attributes: DLL_ENABLE: 0x%x, ODIC: 0x%x(0x%x), AL: 0x%x, WLE: 0x%x, "
             "RTT_NOM:0x%x, TDQS: 0x%x, QOFF: 0x%x", i_rank,
             i_data.iv_dll_enable, i_data.iv_odic[mss::index(i_rank)], uint8_t(l_odic_buffer), uint8_t(l_additive_latency),
             i_data.iv_wl_enable,
             uint8_t(l_rtt_nom_buffer), i_data.iv_tdqs, i_data.iv_qoff);

    io_inst.arr0.writeBit<A0>(i_data.iv_dll_enable);
    mss::swizzle<A1, ODIC_LENGTH, ODIC_START_BIT>(l_odic_buffer, io_inst.arr0);
    mss::swizzle<A3, ADDITIVE_LATENCE_LENGTH, ADDITIVE_LATENCE_START_BIT>(fapi2::buffer<uint8_t>
            (i_data.iv_additive_latency), io_inst.arr0);
    io_inst.arr0.writeBit<A7>(i_data.iv_wl_enable);
    mss::swizzle<A8, RTT_NOM_LENGTH, RTT_NOM_START_BIT>(l_rtt_nom_buffer, io_inst.arr0);
    io_inst.arr0.writeBit<A11>(i_data.iv_tdqs);
    io_inst.arr0.writeBit<A12>(i_data.iv_qoff);

    FAPI_INF("MR1: 0x%016llx", uint64_t(io_inst.arr0));

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Helper function for mrs01_decode
/// @param[in] i_inst the CCS instruction
/// @param[in] i_rank ths rank in question
/// @param[out] o_dll_enable the dll enable bit
/// @param[out] o_wrl_enable the write leveling enable bit
/// @param[out] o_tdqs the tdqs enable bit
/// @param[out] o_qoff the qoff bit
/// @param[out] o_odic the output driver impedance control setting
/// @param[out] o_additive_latency the additive latency setting
/// @param[out] o_rtt_nom the rtt_nom setting
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode mrs01_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
                                      const uint64_t i_rank,
                                      uint8_t& o_dll_enable,
                                      uint8_t& o_wrl_enable,
                                      uint8_t& o_tdqs,
                                      uint8_t& o_qoff,
                                      fapi2::buffer<uint8_t>& o_odic,
                                      fapi2::buffer<uint8_t>& o_additive_latency,
                                      fapi2::buffer<uint8_t>& o_rtt_nom)
{
    o_odic = 0;
    o_additive_latency = 0;
    o_rtt_nom = 0;

    o_dll_enable = i_inst.arr0.getBit<A0>();
    o_wrl_enable = i_inst.arr0.getBit<A7>();
    o_tdqs = i_inst.arr0.getBit<A11>();
    o_qoff = i_inst.arr0.getBit<A12>();

    mss::swizzle<6, 2, A2>(i_inst.arr0, o_odic);
    mss::swizzle<6, 2, A4>(i_inst.arr0, o_additive_latency);
    mss::swizzle<5, 3, A10>(i_inst.arr0, o_rtt_nom);

    FAPI_INF("MR1 rank %d decode: DLL_ENABLE: 0x%x, ODIC: 0x%x, AL: 0x%x, WLE: 0x%x, "
             "RTT_NOM: 0x%x, TDQS: 0x%x, QOFF: 0x%x", i_rank,
             o_dll_enable, uint8_t(o_odic), uint8_t(o_additive_latency), o_wrl_enable, uint8_t(o_rtt_nom),
             o_tdqs, o_qoff);

    return FAPI2_RC_SUCCESS;
}

///
/// @brief Given a CCS instruction which contains address bits with an encoded MRS1,
/// decode and trace the contents
/// @param[in] i_inst the CCS instruction
/// @param[in] i_rank ths rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode mrs01_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
                               const uint64_t i_rank)
{
    uint8_t l_dll_enable = 0;
    uint8_t l_wrl_enable = 0;
    uint8_t l_tdqs = 0;
    uint8_t l_qoff = 0;
    fapi2::buffer<uint8_t> l_odic;
    fapi2::buffer<uint8_t> l_additive_latency;
    fapi2::buffer<uint8_t> l_rtt_nom;

    return mrs01_decode_helper(i_inst, i_rank, l_dll_enable, l_wrl_enable, l_tdqs, l_qoff, l_odic,
                               l_additive_latency, l_rtt_nom);
}

fapi2::ReturnCode (*mrs01_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
        const mrs01_data& i_data,
        ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
        const uint64_t i_rank) = &mrs01;

fapi2::ReturnCode (*mrs01_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
                                        const uint64_t i_rank) = &mrs01_decode;

} // ns ddr4

} // ns mss
<|endoftext|>


<commit_before>#include <iostream>

#include "sani/platform/platform_config.hpp"
#if SANI_TARGET_PLATFORM == SANI_PLATFORM_WIN32

#pragma comment(lib, "OpenGL32.lib")

#include <Windows.h>

#include "sani/graphics/renderer.hpp"
#include "sani/platform/graphics/color.hpp"
#include "sani/platform/graphics/graphics_device.hpp"
#include "sani/platform/graphics/window.hpp"
#include "sani/platform/graphics/viewport.hpp"
#include "sani/platform/graphics/render_target_2d.hpp"
#include "sani/debug.hpp"
#include "sani/graphics/camera2d.hpp"
#include "sani/graphics/renderer.hpp"
#include "sani/core/math/vector.hpp"

using namespace sani::graphics;
using namespace sani::math;

#include "sani/platform/file/file_system.hpp"
#include "sani/platform/file/file_stream.hpp"
#include "sani/resource/resources.hpp"
#include "sani/resource/texture2d.hpp"
using namespace sani::resource;

Texture2D* tuksu = nullptr;
ResourceManager* resourceManager = nullptr;
FileSystem* fileSystem = new FileSystem();

void initResource(GraphicsDevice* gdevice) {
	resourceManager = new ResourceManager(fileSystem, gdevice);
}
/*
	To test if our window, context etc even work.
*/
void glDraw() {
	GLuint VertexArrayID;
	glGenVertexArrays(1, &VertexArrayID);
	glBindVertexArray(VertexArrayID);

	// An array of 3 vectors which represents 3 vertices
	static const GLfloat g_vertex_buffer_data[] = {
		-1.0f, -1.0f, 0.0f,
		1.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
	};

	// This will identify our vertex buffer
	GLuint vertexbuffer;

	// Generate 1 buffer, put the resulting identifier in vertexbuffer
	glGenBuffers(1, &vertexbuffer);

	// The following commands will talk about our 'vertexbuffer' buffer
	glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

	// Give our vertices to OpenGL.
	glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

	// 1rst attribute buffer : vertices
	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
	glVertexAttribPointer(
		0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
		3,                  // size
		GL_FLOAT,           // type
		GL_FALSE,           // normalized?
		0,                  // stride
		(void*)0            // array buffer offset
		);

	// Draw the triangle !
	//glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle

	glDisableVertexAttribArray(0);

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	WIN32_ASSERT();

	Window window(hInstance, 1280, 720);
	window.initialize();
	window.show();

	WIN32_ASSERT();

	GraphicsDevice graphicsDevice(window.getHandle(), hInstance, 1280, 720);
	graphicsDevice.initialize();

	initResource(&graphicsDevice);
	tuksu = static_cast<Texture2D*>(resourceManager->load("../../assets/tuksu.out"));

	Buffer<float32> vertices(1024, BufferSizing::Dynamic);

	Vec3 v1(-0.5f, -0.5f, 0.0f);
	Vec3 v2(0.5f, -0.5f, 0.0f);
	Vec3 v3(0.5f, 0.5f, 0.0f);

	for (size_t i = 0; i < 32; i++)
	{
		Vec3 v1(-0.5f + i, -0.5f + i, 0.0f);
		Vec3 v2(0.5f + i, -0.5f + i, 0.0f);
		Vec3 v3(0.5f + i, 0.5f + i, 0.0f);

		Vec3 v4(0.5f + i, 0.5f + i, 0.0f);
		Vec3 v5(-0.5f + i , 0.5f + i, 0.0f);
		Vec3 v6(-0.5f + i, -0.5f + i, 0.0f);

		Vec3 vert[] = {
			v1, Vec3(1, 0, 0),
			v2, Vec3(0, 1, 0),
			v3, Vec3(1, 0, 0),
			v4, Vec3(0, 0, 1),
			v5, Vec3(1, 0, 0),
			v6, Vec3(1, 1, 0)
		};

		vertices.push(reinterpret_cast<float32*>(vert), 36);
	}

	char* vertexSource =
		"#version 330 core\n"
		"layout(location = 0) in vec3 vertex_position;"
		"layout(location = 1) in vec3 color;"
		"out vec3 out_color;"
		"uniform mat4 transform;"
		"void main() {"
		""
		"	gl_Position = transform * vec4(vertex_position, 1.0);"
		"	out_color = color;"
		"}";

	char* fragmentSource =
		"#version 330 core\n"
		"in vec3 out_color;"
		"out vec3 vertex_color;"
		"void main(){"
		"vertex_color = out_color;"
		"}";

	uint32 vertex = 0;
	uint32 fragment = 0;
	uint32 program = 0;

	Camera2D camera(graphicsDevice.getViewport());
	camera.computeTransformation();

	graphicsDevice.compileShader(vertex, vertexSource, ShaderType::Vertex);
	assert(!graphicsDevice.hasErrors());

	graphicsDevice.compileShader(fragment, fragmentSource, ShaderType::Fragment);
	assert(!graphicsDevice.hasErrors());

	graphicsDevice.createProgram(program);
	graphicsDevice.linkToProgram(program, vertex, true);
	graphicsDevice.linkToProgram(program, fragment, true);
	graphicsDevice.linkProgram(program);
	graphicsDevice.useProgram(program);

	Renderer renderer(graphicsDevice);
	renderer.initialize();

	window.sizeChanged += SANI_EVENT_HANDLER(void(), ([&window, &graphicsDevice, &camera]() {
		Viewport viewport;

		viewport.width = window.getClientWidth();
		viewport.height = window.getClientHeight();

		graphicsDevice.setViewport(viewport);

		graphicsDevice.setBackBufferWidth(viewport.width);
		graphicsDevice.setBackBufferHeight(viewport.height);

		camera.setViewport(graphicsDevice.getViewport());
	}));

	camera.setZoom(1.0f);

	while (window.isOpen()) {
		if (graphicsDevice.hasErrors()) break;

		window.listen();

		camera.computeTransformation();
		sani::math::Mat4f transform = camera.transformation();
		graphicsDevice.setShaderUniform(program, "transform", (void*)&transform, UniformType::Mat4F);

		graphicsDevice.clear(Color::black);

		renderer.beginRenderingPolygons(transform, 6, RenderMode::Triangles);

		renderer.renderPolygons(vertices.head(), vertices.getBufferPointerLocation());

		renderer.endRendering();
	}

	graphicsDevice.cleanUp();

	return 0;
}

#endif<commit_msg>black screen of vitutus<commit_after>#include <iostream>

#include "sani/platform/platform_config.hpp"
#if SANI_TARGET_PLATFORM == SANI_PLATFORM_WIN32

#pragma comment(lib, "OpenGL32.lib")

#include <Windows.h>

#include "sani/graphics/renderer.hpp"
#include "sani/platform/graphics/color.hpp"
#include "sani/platform/graphics/graphics_device.hpp"
#include "sani/platform/graphics/window.hpp"
#include "sani/platform/graphics/viewport.hpp"
#include "sani/platform/graphics/render_target_2d.hpp"
#include "sani/debug.hpp"
#include "sani/graphics/camera2d.hpp"
#include "sani/graphics/renderer.hpp"
#include "sani/core/math/vector.hpp"

using namespace sani::graphics;
using namespace sani::math;

#include "sani/platform/file/file_system.hpp"
#include "sani/platform/file/file_stream.hpp"
#include "sani/resource/resources.hpp"
#include "sani/resource/texture2d.hpp"
using namespace sani::resource;

Texture2D* tuksu = nullptr;
ResourceManager* resourceManager = nullptr;
FileSystem* fileSystem = new FileSystem();

void initResource(GraphicsDevice* gdevice) {
	resourceManager = new ResourceManager(fileSystem, gdevice);
}
/*
	To test if our window, context etc even work.
*/
void glDraw() {
	GLuint VertexArrayID;
	glGenVertexArrays(1, &VertexArrayID);
	glBindVertexArray(VertexArrayID);

	// An array of 3 vectors which represents 3 vertices
	static const GLfloat g_vertex_buffer_data[] = {
		-1.0f, -1.0f, 0.0f,
		1.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
	};

	// This will identify our vertex buffer
	GLuint vertexbuffer;

	// Generate 1 buffer, put the resulting identifier in vertexbuffer
	glGenBuffers(1, &vertexbuffer);

	// The following commands will talk about our 'vertexbuffer' buffer
	glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

	// Give our vertices to OpenGL.
	glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

	// 1rst attribute buffer : vertices
	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
	glVertexAttribPointer(
		0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
		3,                  // size
		GL_FLOAT,           // type
		GL_FALSE,           // normalized?
		0,                  // stride
		(void*)0            // array buffer offset
		);

	// Draw the triangle !
	//glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle

	glDisableVertexAttribArray(0);

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	WIN32_ASSERT();

	Window window(hInstance, 1280, 720);
	window.initialize();
	window.show();

	WIN32_ASSERT();

	GraphicsDevice graphicsDevice(window.getHandle(), hInstance, 1280, 720);
	graphicsDevice.initialize();

	initResource(&graphicsDevice);
	tuksu = static_cast<Texture2D*>(resourceManager->load("../../assets/tuksu.out"));

	Buffer<float32> vertices(1024, BufferSizing::Dynamic);

	Vec3 v1(-32, -32, 0.0f);
	Vec3 v2(32, -32, 0.0f);
	Vec3 v3(32, 32, 0.0f);

	for (size_t i = 0; i < 32; i++)
	{
		Vec3 v1(-32 + i, -32 + i, 0.0f);
		Vec3 v2(32 + i, -32 + i, 0.0f);
		Vec3 v3(32 + i, 32 + i, 0.0f);

		Vec3 v4(32 + i, 32 + i, 0.0f);
		Vec3 v5(-32 + i , 32 + i, 0.0f);
		Vec3 v6(-32 + i, -32 + i, 0.0f);

		Vec3 vert[] = {
			v1, Vec3(1, 0, 0),
			v2, Vec3(0, 1, 0),
			v3, Vec3(1, 0, 0),
			v4, Vec3(0, 0, 1),
			v5, Vec3(1, 0, 0),
			v6, Vec3(1, 1, 0)
		};

		vertices.push(reinterpret_cast<float32*>(vert), 36);
	}

	char* vertexSource =
		"#version 330 core\n"
		"layout(location = 0) in vec3 vertex_position;"
		"layout(location = 1) in vec3 color;"
		"out vec3 out_color;"
		"uniform mat4 transform;"
		"void main() {"
		""
		"	gl_Position = transform * vec4(vertex_position, 1.0);"
		"	out_color = color;"
		"}";

	char* fragmentSource =
		"#version 330 core\n"
		"in vec3 out_color;"
		"out vec3 vertex_color;"
		"void main(){"
		"vertex_color = out_color;"
		"}";

	uint32 vertex = 0;
	uint32 fragment = 0;
	uint32 program = 0;

	Camera2D camera(graphicsDevice.getViewport());
	camera.computeTransformation();

	graphicsDevice.compileShader(vertex, vertexSource, ShaderType::Vertex);
	assert(!graphicsDevice.hasErrors());

	graphicsDevice.compileShader(fragment, fragmentSource, ShaderType::Fragment);
	assert(!graphicsDevice.hasErrors());

	graphicsDevice.createProgram(program);
	graphicsDevice.linkToProgram(program, vertex, true);
	graphicsDevice.linkToProgram(program, fragment, true);
	graphicsDevice.linkProgram(program);
	graphicsDevice.useProgram(program);

	Renderer renderer(graphicsDevice);
	renderer.initialize();

	window.sizeChanged += SANI_EVENT_HANDLER(void(), ([&window, &graphicsDevice, &camera]() {
		Viewport viewport;

		viewport.width = window.getClientWidth();
		viewport.height = window.getClientHeight();

		graphicsDevice.setViewport(viewport);

		graphicsDevice.setBackBufferWidth(viewport.width);
		graphicsDevice.setBackBufferHeight(viewport.height);

		camera.setViewport(graphicsDevice.getViewport());
	}));

	camera.setZoom(1.0f);

	while (window.isOpen()) {
		if (graphicsDevice.hasErrors()) break;

		window.listen();

		camera.computeTransformation();
		sani::math::Mat4f transform = camera.transformation();
		graphicsDevice.setShaderUniform(program, "transform", (void*)&transform, UniformType::Mat4F);

		graphicsDevice.clear(Color::black);

		renderer.beginRenderingPolygons(transform, 6, RenderMode::Triangles);

		renderer.renderPolygons(vertices.head(), vertices.getBufferPointerLocation());

		renderer.endRendering();
	}

	graphicsDevice.cleanUp();

	return 0;
}

#endif<|endoftext|>