This source file includes following definitions.
- create_buffer
- run_cpu_filter
- run_opengl_filter_from_host_to_host
- run_opengl_filter_from_texture_to_texture
- main
- halide_opengl_create_context
#include <iostream>
#include <stdlib.h>
#include "png_helpers.h"
#include "glfw_helpers.h"
#include "opengl_helpers.h"
#include "layout.h"
#include "timer.h"
#include <HalideRuntimeOpenGL.h>
#include "sample_filter_cpu.h"
#include "sample_filter_opengl.h"
buffer_t create_buffer(int width, int height)
{
const int channels = 4;
const int elem_size = 1;
buffer_t buf = {0};
buf.stride[0] = channels;
buf.stride[1] = channels * width;
buf.stride[2] = 1;
buf.elem_size = elem_size;
buf.extent[0] = width;
buf.extent[1] = height;
buf.extent[2] = channels;
return buf;
}
std::string run_cpu_filter(const uint8_t *image_data, uint8_t *result_data, int width, int height)
{
const auto time = Timer::start("CPU");
auto input_buf = create_buffer(width, height);
input_buf.host = (uint8_t *) image_data;
auto output_buf = create_buffer(width, height);
output_buf.host = result_data;
sample_filter_cpu(&input_buf, &output_buf);
return Timer::report(time);
}
std::string run_opengl_filter_from_host_to_host(const uint8_t *image_data, uint8_t *result_data, int width, int height)
{
const auto time = Timer::start("OpenGL host-to-host");
auto input_buf = create_buffer(width, height);
input_buf.host = (uint8_t *) image_data;
input_buf.host_dirty = true;
auto output_buf = create_buffer(width, height);
output_buf.host = result_data;
sample_filter_opengl(&input_buf, &output_buf);
halide_copy_to_host(nullptr, &output_buf);
return Timer::report(time);
}
std::string run_opengl_filter_from_texture_to_texture(GLuint input_texture_id, GLuint output_texture_id, int width, int height)
{
const auto time = Timer::start("OpenGL texture-to-texture");
auto input_buf = create_buffer(width, height);
halide_opengl_wrap_texture(nullptr, &input_buf, input_texture_id);
auto output_buf = create_buffer(width, height);
halide_opengl_wrap_texture(nullptr, &output_buf, output_texture_id);
sample_filter_opengl(&input_buf, &output_buf);
halide_opengl_detach_texture(nullptr, &output_buf);
halide_opengl_detach_texture(nullptr, &input_buf);
return Timer::report(time);
}
int main(const int argc, const char *argv[])
{
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " filename" << std::endl;
exit(1);
}
const std::string filename = argv[1];
const auto image = PNGHelpers::load(filename);
const auto width = image.width;
const auto height = image.height;
const auto layout = Layout::setup(width, height);
const auto glfw = GlfwHelpers::setup(layout.window_width, layout.window_height);
OpenGLHelpers::setup(glfw.dpi_scale);
Layout::draw_image(Layout::UL, image.data, width, height, "Input");
std::string report;
const auto cpu_result_data = (uint8_t *) calloc(width * height * 4, sizeof(uint8_t));
report = run_cpu_filter(image.data, cpu_result_data, width, height);
Layout::draw_image(Layout::UR, cpu_result_data, width, height, report);
free((void*) cpu_result_data);
const auto opengl_result_data = (uint8_t *) calloc(width * height * 4, sizeof(uint8_t));
report = run_opengl_filter_from_host_to_host(image.data, opengl_result_data, width, height);
Layout::draw_image(Layout::LL, opengl_result_data, width, height, report);
free((void*) opengl_result_data);
const auto image_texture_id = OpenGLHelpers::create_texture(width, height, image.data);
const auto result_texture_id = OpenGLHelpers::create_texture(width, height, nullptr);
report = run_opengl_filter_from_texture_to_texture(image_texture_id, result_texture_id, width, height);
Layout::draw_texture(Layout::LR, result_texture_id, width, height, report);
OpenGLHelpers::delete_texture(image_texture_id);
OpenGLHelpers::delete_texture(result_texture_id);
halide_opengl_context_lost(nullptr);
GlfwHelpers::terminate();
free((void*) image.data);
return 0;
}
int halide_opengl_create_context(void * )
{
GlfwHelpers::set_opengl_context();
return 0;
}