Commit e31fb7a7 authored by Kenneth Moreland's avatar Kenneth Moreland

Added test for icetCompositeImage function.

Also fixed some glaring problems with compositing pre-rendered images.
parent 7aed1a73
......@@ -118,7 +118,7 @@
if (_composite_mode == ICET_COMPOSITE_MODE_Z_BUFFER) {
if (_depth_format == ICET_IMAGE_DEPTH_FLOAT) {
/* Use Z buffer for active pixel testing. */
const IceTFloat *_depth = icetImageGetDepthf(INPUT_IMAGE);
const IceTFloat *_depth = icetImageGetDepthcf(INPUT_IMAGE);
#ifdef OFFSET
_depth += OFFSET;
#endif
......@@ -129,7 +129,7 @@
#ifdef REGION
IceTSizeType _region_count = 0;
#endif
_color = icetImageGetColorui(INPUT_IMAGE);
_color = icetImageGetColorcui(INPUT_IMAGE);
#ifdef OFFSET
_color += OFFSET;
#endif
......@@ -171,7 +171,7 @@
#ifdef REGION
IceTSizeType _region_count = 0;
#endif
_color = icetImageGetColorf(INPUT_IMAGE);
_color = icetImageGetColorcf(INPUT_IMAGE);
#ifdef OFFSET
_color += 4*(OFFSET);
#endif
......@@ -265,7 +265,7 @@
#ifdef REGION
IceTSizeType _region_count = 0;
#endif
_color = icetImageGetColorui(INPUT_IMAGE);
_color = icetImageGetColorcui(INPUT_IMAGE);
#ifdef OFFSET
_color += OFFSET;
#endif
......@@ -303,7 +303,7 @@
#ifdef REGION
IceTSizeType _region_count = 0;
#endif
_color = icetImageGetColorf(INPUT_IMAGE);
_color = icetImageGetColorcf(INPUT_IMAGE);
#ifdef OFFSET
_color += 4*(OFFSET);
#endif
......
......@@ -13,6 +13,7 @@
#include <IceTDevDiagnostics.h>
#include <IceTDevImage.h>
#include <IceTDevMatrix.h>
#include <IceTDevProjections.h>
#include <IceTDevState.h>
#include <IceTDevStrategySelect.h>
#include <IceTDevTiming.h>
......@@ -635,22 +636,9 @@ static void drawProjectBounds(void)
* viewport with that one. */
const IceTInt *rendered_viewport =
icetUnsafeStateGetInteger(ICET_RENDERED_VIEWPORT);
if (rendered_viewport[0] > contained_viewport[0]) {
contained_viewport[2] -= rendered_viewport[0]-contained_viewport[0];
if (contained_viewport[2] < 0) { contained_viewport[2] = 0; }
contained_viewport[0] = rendered_viewport[0];
}
if (rendered_viewport[2] < contained_viewport[2]) {
contained_viewport[2] = rendered_viewport[2];
}
if (rendered_viewport[1] > contained_viewport[1]) {
contained_viewport[3] -= rendered_viewport[1]-contained_viewport[1];
if (contained_viewport[3] < 0) { contained_viewport[3] = 0; }
contained_viewport[1] = rendered_viewport[1];
}
if (rendered_viewport[3] < contained_viewport[3]) {
contained_viewport[3] = rendered_viewport[3];
}
icetIntersectViewports(rendered_viewport,
contained_viewport,
contained_viewport);
}
/* Now use this information to figure out which tiles need to be
......
......@@ -1044,7 +1044,7 @@ void icetImageCopyPixels(const IceTImage in_image, IceTSizeType in_offset,
const IceTByte *in_colors; /* Use IceTByte for pointer arithmetic */
IceTByte *out_colors;
IceTSizeType pixel_size;
in_colors = icetImageGetColorVoid(in_image, &pixel_size);
in_colors = icetImageGetColorConstVoid(in_image, &pixel_size);
out_colors = icetImageGetColorVoid(out_image, NULL);
memcpy(out_colors + pixel_size*out_offset,
in_colors + pixel_size*in_offset,
......@@ -1055,7 +1055,7 @@ void icetImageCopyPixels(const IceTImage in_image, IceTSizeType in_offset,
const IceTByte *in_depths; /* Use IceTByte for pointer arithmetic */
IceTByte *out_depths;
IceTSizeType pixel_size;
in_depths = icetImageGetDepthVoid(in_image, &pixel_size);
in_depths = icetImageGetDepthConstVoid(in_image, &pixel_size);
out_depths = icetImageGetDepthVoid(out_image, NULL);
memcpy(out_depths + pixel_size*out_offset,
in_depths + pixel_size*in_offset,
......@@ -1088,7 +1088,7 @@ void icetImageCopyRegion(const IceTImage in_image,
if (color_format != ICET_IMAGE_COLOR_NONE) {
IceTSizeType pixel_size;
/* Use IceTByte for byte-based pointer arithmetic. */
const IceTByte *src = icetImageGetColorVoid(in_image, &pixel_size);
const IceTByte *src = icetImageGetColorConstVoid(in_image, &pixel_size);
IceTByte *dest = icetImageGetColorVoid(out_image, &pixel_size);
IceTSizeType y;
......@@ -1110,7 +1110,7 @@ void icetImageCopyRegion(const IceTImage in_image,
if (depth_format != ICET_IMAGE_DEPTH_NONE) {
IceTSizeType pixel_size;
/* Use IceTByte for byte-based pointer arithmetic. */
const IceTByte *src = icetImageGetDepthVoid(in_image, &pixel_size);
const IceTByte *src = icetImageGetDepthConstVoid(in_image, &pixel_size);
IceTByte *dest = icetImageGetDepthVoid(out_image, &pixel_size);
IceTSizeType y;
......@@ -1305,13 +1305,26 @@ IceTImage icetImageUnpackageFromReceive(IceTVoid *buffer)
return image;
}
if ( icetImageBufferSizeType(color_format, depth_format,
icetImageGetWidth(image),
icetImageGetHeight(image))
!= ICET_IMAGE_HEADER(image)[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX] ) {
icetRaiseError("Inconsistent sizes in image data.", ICET_INVALID_VALUE);
image.opaque_internals = NULL;
return image;
if (magic_number == ICET_IMAGE_MAGIC_NUM) {
IceTSizeType buffer_size =
ICET_IMAGE_HEADER(image)[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX];
if ( icetImageBufferSizeType(color_format, depth_format,
icetImageGetWidth(image),
icetImageGetHeight(image))
!= buffer_size ) {
icetRaiseError("Inconsistent sizes in image data.", ICET_INVALID_VALUE);
image.opaque_internals = NULL;
return image;
}
} else {
IceTSizeType buffer_size =
ICET_IMAGE_HEADER(image)[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX];
if (buffer_size != -1) {
icetRaiseError("Size information not consistent with image type.",
ICET_INVALID_VALUE);
image.opaque_internals = NULL;
return image;
}
}
/* The source may have used a bigger buffer than allocated here at the
......@@ -2718,36 +2731,15 @@ static IceTImage prerenderedTile(int tile,
contained_viewport = icetUnsafeStateGetInteger(ICET_CONTAINED_VIEWPORT);
tile_viewport = icetUnsafeStateGetInteger(ICET_TILE_VIEWPORTS) + 4*tile;
/* Start with the tile viewport. */
screen_viewport[0] = tile_viewport[0];
screen_viewport[1] = tile_viewport[1];
screen_viewport[2] = tile_viewport[2];
screen_viewport[3] = tile_viewport[3];
target_viewport[0] = target_viewport[1] = 0;
/* Clip by the contained viewport. */
if (contained_viewport[0] > screen_viewport[0]) {
IceTInt diff = contained_viewport[0] - screen_viewport[0];
screen_viewport[0] = contained_viewport[0];
target_viewport[0] = diff;
screen_viewport[2] -= diff;
if (screen_viewport[2] < 0) { screen_viewport[2] = 0; }
}
if (contained_viewport[2] < screen_viewport[2]) {
screen_viewport[2] = contained_viewport[2];
}
if (contained_viewport[1] > screen_viewport[1]) {
IceTInt diff = contained_viewport[1] - screen_viewport[1];
screen_viewport[1] = contained_viewport[1];
target_viewport[1] = diff;
screen_viewport[3] -= diff;
if (screen_viewport[3] < 0) { screen_viewport[3] = 0; }
}
if (contained_viewport[3] < screen_viewport[3]) {
screen_viewport[3] = contained_viewport[3];
}
/* The screen viewport is the intersection of the tile viewport with the
* contained viewport. */
icetIntersectViewports(tile_viewport, contained_viewport, screen_viewport);
/* The target viewport is the same width-height as the screen viewport.
* It is offset by the same amount the screen viewport is offset from the
* tile viewport. */
target_viewport[0] = screen_viewport[0] - tile_viewport[0];
target_viewport[1] = screen_viewport[1] - tile_viewport[1];
target_viewport[2] = screen_viewport[2];
target_viewport[3] = screen_viewport[3];
......
......@@ -18,6 +18,13 @@
#include <stdlib.h>
#include <string.h>
#ifndef MIN
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif
#ifndef MAX
#define MAX(x, y) ((x) < (y) ? (y) : (x))
#endif
static void update_tile_projections(void);
......@@ -173,3 +180,36 @@ static void update_tile_projections(void)
tile_projections + 16*tile_idx);
}
}
void icetIntersectViewports(const IceTInt *src_viewport1,
const IceTInt *src_viewport2,
IceTInt *dest_viewport)
{
const IceTInt min_x1 = src_viewport1[0];
const IceTInt max_x1 = min_x1 + src_viewport1[2];
const IceTInt min_y1 = src_viewport1[1];
const IceTInt max_y1 = min_y1 + src_viewport1[3];
const IceTInt min_x2 = src_viewport2[0];
const IceTInt max_x2 = min_x2 + src_viewport2[2];
const IceTInt min_y2 = src_viewport2[1];
const IceTInt max_y2 = min_y2 + src_viewport2[3];
const IceTInt min_x = MAX(min_x1, min_x2);
const IceTInt min_y = MAX(min_y1, min_y2);
const IceTInt max_x = MIN(max_x1, max_x2);
const IceTInt max_y = MIN(max_y1, max_y2);
const IceTInt width = max_x - min_x;
const IceTInt height = max_y - min_y;
if ((width > 0) && (height > 0)) {
dest_viewport[0] = min_x;
dest_viewport[1] = min_y;
dest_viewport[2] = width;
dest_viewport[3] = height;
} else {
dest_viewport[0] = dest_viewport[1] = -1000000;
dest_viewport[2] = dest_viewport[3] = 0;
}
}
......@@ -19,11 +19,25 @@ extern "C" {
}
#endif
/* Given the index to a tile, returns an adjusted ICET_PROJECTION_MATRIX
for the tile. If the physical render size is larger than the tile,
then the tile projection occurs in the lower left corner. */
ICET_EXPORT void icetProjectTile(IceTInt tile, IceTDouble *mat_out);
/* Given a viewport (defined by x, y, width, and height), return a matrix
transforms a projection from the global display to the display provided. */
ICET_EXPORT void icetGetViewportProject(IceTInt x, IceTInt y,
IceTSizeType width, IceTSizeType height,
IceTDouble *mat_out);
IceTSizeType width, IceTSizeType height,
IceTDouble *mat_out);
/* Given two viewports, returns the region that is their intersection. It
is OK if either of the two src_viewport pointer point to the same memory
as dest_viewport. If the intersection is empty, the width and height
of dest_viewport will be 0 and the x and y will be set to -1000000 (to
place them outside of reasonable viewports). */
ICET_EXPORT void icetIntersectViewports(const IceTInt *src_viewport1,
const IceTInt *src_viewport2,
IceTInt *dest_viewport);
#ifdef __cplusplus
}
......
......@@ -50,6 +50,7 @@ SET(MyTests
MaxImageSplit.c
OddImageSizes.c
OddProcessCounts.c
PreRender.c
RadixkUnitTests.c
RenderEmpty.c
SimpleTiming.c
......
......@@ -118,7 +118,7 @@ static void RenderFloatingViewport(const IceTDouble *projection_matrix,
}
}
static void FloatingViewportSetupRender()
static void FloatingViewportSetupRender(void)
{
icetCompositeMode(ICET_COMPOSITE_MODE_BLEND);
icetSetColorFormat(ICET_IMAGE_COLOR_RGBA_FLOAT);
......@@ -213,7 +213,7 @@ static IceTBoolean FloatingViewportCheckImage(const IceTImage image)
return ICET_TRUE;
}
static IceTBoolean FloatingViewportTryRender()
static IceTBoolean FloatingViewportTryRender(void)
{
IceTDouble projection_matrix[16];
IceTDouble modelview_matrix[16];
......@@ -237,7 +237,7 @@ static IceTBoolean FloatingViewportTryRender()
return FloatingViewportCheckImage(image);
}
static int FloatingViewportTryMultipleRenders()
static int FloatingViewportTryMultipleRenders(void)
{
IceTBoolean success = ICET_TRUE;
IceTInt trial;
......
/* -*- c -*- *****************************************************************
** Copyright (C) 2014 Sandia Corporation
** Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
** the U.S. Government retains certain rights in this software.
**
** This source code is released under the New BSD License.
**
** Tests the icetCompositeImage method to composite an image that has been
** pre-rendered (as opposed to rendered on demand through callbacks).
*****************************************************************************/
#include <IceT.h>
#include <IceTDevCommunication.h>
#include <IceTDevState.h>
#include "test_codes.h"
#include "test-util.h"
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
static IceTInt g_local_valid_pixel_viewport[4];
static IceTInt *g_all_valid_pixel_viewports;
static void SetUpTiles(IceTInt tile_dimension)
{
IceTInt tile_index = 0;
IceTInt tile_x;
IceTInt tile_y;
icetResetTiles();
for (tile_y = 0; tile_y < tile_dimension; tile_y++) {
for (tile_x = 0; tile_x < tile_dimension; tile_x++) {
icetAddTile(tile_x*SCREEN_WIDTH,
tile_y*SCREEN_HEIGHT,
SCREEN_WIDTH,
SCREEN_HEIGHT,
tile_index);
tile_index++;
}
}
}
static void MakeValidPixelViewports()
{
IceTInt global_viewport[4];
IceTInt global_width;
IceTInt global_height;
IceTInt value1, value2;
icetGetIntegerv(ICET_GLOBAL_VIEWPORT, global_viewport);
global_width = global_viewport[2];
global_height = global_viewport[3];
value1 = rand()%global_width; value2 = rand()%global_height;
if (value1 < value2) {
g_local_valid_pixel_viewport[0] = value1;
g_local_valid_pixel_viewport[2] = value2 - value1;
} else {
g_local_valid_pixel_viewport[0] = value2;
g_local_valid_pixel_viewport[2] = value1 - value2;
}
value1 = rand()%global_width; value2 = rand()%global_height;
if (value1 < value2) {
g_local_valid_pixel_viewport[1] = value1;
g_local_valid_pixel_viewport[3] = value2 - value1;
} else {
g_local_valid_pixel_viewport[1] = value2;
g_local_valid_pixel_viewport[3] = value1 - value2;
}
icetCommAllgather(g_local_valid_pixel_viewport,
4,
ICET_INT,
g_all_valid_pixel_viewports);
}
static void MakeImageBuffers(IceTUInt **color_buffer_p,
IceTFloat **depth_buffer_p)
{
IceTUInt *color_buffer;
IceTFloat *depth_buffer;
IceTInt global_viewport[4];
IceTInt rank;
IceTInt num_proc;
IceTInt width;
IceTInt height;
IceTInt x;
IceTInt y;
IceTInt pixel;
IceTInt left;
IceTInt right;
IceTInt bottom;
IceTInt top;
icetGetIntegerv(ICET_GLOBAL_VIEWPORT, global_viewport);
width = global_viewport[2];
height = global_viewport[3];
icetGetIntegerv(ICET_RANK, &rank);
icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc);
left = g_local_valid_pixel_viewport[0];
right = left + g_local_valid_pixel_viewport[2];
bottom = g_local_valid_pixel_viewport[1];
top = bottom + g_local_valid_pixel_viewport[3];
color_buffer = malloc(width*height*sizeof(IceTUInt));
depth_buffer = malloc(width*height*sizeof(IceTFloat));
pixel = 0;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
if ((x >= left) && (x < right) && (y >= bottom) && (y < top)) {
color_buffer[pixel] = rank;
depth_buffer[pixel] = ((IceTFloat)rank)/num_proc;
} else {
color_buffer[pixel] = 0xDEADDEAD; /* garbage value */
}
pixel++;
}
}
*color_buffer_p = color_buffer;
*depth_buffer_p = depth_buffer;
}
static IceTBoolean CheckCompositedImage(const IceTImage image)
{
IceTInt tile_displayed;
const IceTUInt *color_buffer;
IceTSizeType width;
IceTSizeType height;
const IceTInt *tile_viewport;
IceTInt local_x, local_y;
IceTInt global_x, global_y;
IceTInt num_proc;
icetGetIntegerv(ICET_VALID_PIXELS_TILE, &tile_displayed);
if (tile_displayed < 0) {
/* No local tile. Nothing to compare. Just return success. */
return ICET_TRUE;
}
icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc);
color_buffer = icetImageGetColorcui(image);
width = icetImageGetWidth(image);
height = icetImageGetHeight(image);
tile_viewport =
icetUnsafeStateGetInteger(ICET_TILE_VIEWPORTS) + 4*tile_displayed;
if ((tile_viewport[2] != width) || (tile_viewport[3] != height)) {
printrank("***** Tile width or height does not match image! *****\n");
printrank("Tile: %d x %d\n", tile_viewport[2], tile_viewport[3]);
printrank("Image: %d x %d\n", width, height);
return ICET_FALSE;
}
for (local_y = 0, global_y = tile_viewport[1];
local_y < height;
local_y++, global_y++) {
for (local_x = 0, global_x = tile_viewport[0];
local_x < width;
local_x++, global_x++) {
IceTUInt image_value;
IceTUInt expected_value;
IceTInt proc_index;
image_value = color_buffer[local_x + local_y*width];
expected_value = 0xFFFFFFFF;
for (proc_index = 0; proc_index < num_proc; proc_index++) {
IceTInt *proc_viewport =
g_all_valid_pixel_viewports + 4*proc_index;
if ( (global_x >= proc_viewport[0])
&& (global_x < proc_viewport[0]+proc_viewport[2])
&& (global_y >= proc_viewport[1])
&& (global_y < proc_viewport[1]+proc_viewport[3]) ) {
expected_value = proc_index;
break;
}
}
if (image_value != expected_value) {
printrank("***** Got an unexpected value in the image *****\n");
printrank("Located at pixel %d,%d (globally %d,%d)\n",
local_x, local_y, global_x, global_y);
printrank("Expected 0x%X. Got 0x%X\n",
expected_value, image_value);
return ICET_FALSE;
}
}
}
return ICET_TRUE;
}
static IceTBoolean PreRenderTryComposite(IceTUInt *color_buffer,
IceTFloat *depth_buffer)
{
IceTFloat background_color[4] = { 1.0, 1.0, 1.0, 1.0 };
IceTImage image;
icetSetColorFormat(ICET_IMAGE_COLOR_RGBA_UBYTE);
icetSetDepthFormat(ICET_IMAGE_DEPTH_FLOAT);
icetCompositeMode(ICET_COMPOSITE_MODE_Z_BUFFER);
icetDisable(ICET_ORDERED_COMPOSITE);
image = icetCompositeImage(color_buffer,
depth_buffer,
g_local_valid_pixel_viewport,
NULL,
NULL,
background_color);
return CheckCompositedImage(image);
}
static IceTBoolean PreRenderTryStrategy()
{
IceTBoolean success = ICET_TRUE;
IceTUInt *color_buffer;
IceTFloat *depth_buffer;
IceTInt strategy_index;
MakeImageBuffers(&color_buffer, &depth_buffer);
for (strategy_index = 0;
strategy_index < STRATEGY_LIST_SIZE;
strategy_index++) {
icetStrategy(strategy_list[strategy_index]);
printstat(" Using %s strategy.\n", icetGetStrategyName());
success &= PreRenderTryComposite(color_buffer, depth_buffer);
}
free(color_buffer);
free(depth_buffer);
return success;
}
static IceTBoolean PreRenderTryTiles(void)
{
IceTBoolean success = ICET_TRUE;
IceTInt num_proc;
IceTInt tile_dimension;
icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc);
for (tile_dimension = 1;
(tile_dimension <= 4) && (tile_dimension*tile_dimension <= num_proc);
tile_dimension++) {
printstat("\nUsing %dx%d tiles\n", tile_dimension, tile_dimension);
SetUpTiles(tile_dimension);
MakeValidPixelViewports();
success &= PreRenderTryStrategy();
}
return success;
}
static int PreRenderRun(void)
{
IceTInt rank;
IceTInt num_proc;
unsigned int seed;
icetGetIntegerv(ICET_RANK, &rank);
icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc);
g_all_valid_pixel_viewports = malloc(4*num_proc*sizeof(IceTInt));
/* Establish a random seed. */
if (rank == 0) {
IceTInt remote_process;
seed = (int)time(NULL);
printstat("Base seed = %u\n", seed);
srand(seed);
for (remote_process = 1; remote_process < num_proc; remote_process++) {
icetCommSend(&seed, 1, ICET_INT, remote_process, 29);
}
} else {
icetCommRecv(&seed, 1, ICET_INT, 0, 29);
srand(seed + rank);
}
{
IceTBoolean success = PreRenderTryTiles();
free(g_all_valid_pixel_viewports);
return (success ? TEST_PASSED : TEST_FAILED);
}
}
int PreRender(int argc, char *argv[])
{
/* Suppress warning. */
(void)argc;
(void)argv;
return run_test(PreRenderRun);
}
......@@ -198,11 +198,13 @@ void initialize_test(int *argcp, char ***argvp, IceTCommunicator comm)
/* This is convenient code to attach a debugger to a particular process at the
start of a test. */
/* if (rank == 0) { */
/* int i = 0; */
/* printf("Waiting in process %d\n", getpid()); */
/* while (i == 0) sleep(1); */
/* } */
#if 0
if (rank == 0) {
int i = 0;
printf("Waiting in process %d\n", getpid());
while (i == 0) sleep(1);
}
#endif
#ifdef ICET_TESTS_USE_GLUT
/* Let Glut have first pass at the arguments to grab any that it can use. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment