Super slow MicroProfile GL UI.
This commit is contained in:
560
src/xenia/gpu/gl4/gl4_profiler_display.cc
Normal file
560
src/xenia/gpu/gl4/gl4_profiler_display.cc
Normal file
@@ -0,0 +1,560 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2015 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/gpu/gl4/gl4_profiler_display.h>
|
||||
|
||||
#include <third_party/microprofile/microprofileui.h>
|
||||
|
||||
#include <poly/cxx_compat.h>
|
||||
#include <poly/math.h>
|
||||
#include <xenia/gpu/gpu-private.h>
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace gl4 {
|
||||
|
||||
extern "C" GLEWContext* glewGetContext();
|
||||
|
||||
#define MICROPROFILE_MAX_VERTICES (16 << 10)
|
||||
#define MICROPROFILE_NUM_QUERIES (8 << 10)
|
||||
#define MAX_FONT_CHARS 256
|
||||
#define Q0(d, member, v) d[0].member = v
|
||||
#define Q1(d, member, v) \
|
||||
d[1].member = v; \
|
||||
d[3].member = v
|
||||
#define Q2(d, member, v) d[4].member = v
|
||||
#define Q3(d, member, v) \
|
||||
d[2].member = v; \
|
||||
d[5].member = v
|
||||
|
||||
const int FONT_TEX_X = 1024;
|
||||
const int FONT_TEX_Y = 9;
|
||||
|
||||
const uint8_t profiler_font[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x78, 0x38, 0x78,
|
||||
0x7c, 0x7c, 0x3c, 0x44, 0x38, 0x04, 0x44, 0x40, 0x44, 0x44, 0x38, 0x78,
|
||||
0x38, 0x78, 0x38, 0x7c, 0x44, 0x44, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x00,
|
||||
0x40, 0x00, 0x04, 0x00, 0x18, 0x00, 0x40, 0x10, 0x08, 0x40, 0x30, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x10, 0x38, 0x7c, 0x08, 0x7c, 0x1c, 0x7c, 0x38, 0x38,
|
||||
0x10, 0x28, 0x28, 0x10, 0x00, 0x20, 0x10, 0x08, 0x10, 0x10, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, 0x38, 0x38, 0x70, 0x00,
|
||||
0x1c, 0x10, 0x00, 0x1c, 0x10, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x28, 0x44, 0x44, 0x44, 0x40, 0x40, 0x40, 0x44,
|
||||
0x10, 0x04, 0x48, 0x40, 0x6c, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x10,
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x04, 0x00, 0x00, 0x40, 0x00, 0x04, 0x00,
|
||||
0x24, 0x00, 0x40, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x30,
|
||||
0x44, 0x04, 0x18, 0x40, 0x20, 0x04, 0x44, 0x44, 0x10, 0x28, 0x28, 0x3c,
|
||||
0x44, 0x50, 0x10, 0x10, 0x08, 0x54, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00,
|
||||
0x00, 0x08, 0x00, 0x10, 0x44, 0x44, 0x40, 0x40, 0x04, 0x28, 0x00, 0x30,
|
||||
0x10, 0x18, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x44, 0x44, 0x40, 0x44, 0x40, 0x40, 0x40, 0x44, 0x10, 0x04, 0x50, 0x40,
|
||||
0x54, 0x64, 0x44, 0x44, 0x44, 0x44, 0x40, 0x10, 0x44, 0x44, 0x44, 0x28,
|
||||
0x28, 0x08, 0x00, 0x38, 0x78, 0x3c, 0x3c, 0x38, 0x20, 0x38, 0x78, 0x30,
|
||||
0x18, 0x44, 0x10, 0x6c, 0x78, 0x38, 0x78, 0x3c, 0x5c, 0x3c, 0x3c, 0x44,
|
||||
0x44, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x4c, 0x10, 0x04, 0x08, 0x28, 0x78,
|
||||
0x40, 0x08, 0x44, 0x44, 0x10, 0x00, 0x7c, 0x50, 0x08, 0x50, 0x00, 0x20,
|
||||
0x04, 0x38, 0x10, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x10, 0x7c, 0x08,
|
||||
0x08, 0x54, 0x40, 0x20, 0x04, 0x44, 0x00, 0x30, 0x10, 0x18, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x78, 0x40, 0x44,
|
||||
0x78, 0x78, 0x40, 0x7c, 0x10, 0x04, 0x60, 0x40, 0x54, 0x54, 0x44, 0x78,
|
||||
0x44, 0x78, 0x38, 0x10, 0x44, 0x44, 0x54, 0x10, 0x10, 0x10, 0x00, 0x04,
|
||||
0x44, 0x40, 0x44, 0x44, 0x78, 0x44, 0x44, 0x10, 0x08, 0x48, 0x10, 0x54,
|
||||
0x44, 0x44, 0x44, 0x44, 0x60, 0x40, 0x10, 0x44, 0x44, 0x44, 0x28, 0x44,
|
||||
0x08, 0x00, 0x54, 0x10, 0x18, 0x18, 0x48, 0x04, 0x78, 0x10, 0x38, 0x3c,
|
||||
0x10, 0x00, 0x28, 0x38, 0x10, 0x20, 0x00, 0x20, 0x04, 0x10, 0x7c, 0x00,
|
||||
0x7c, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x04, 0x10, 0x5c, 0x40, 0x10,
|
||||
0x04, 0x00, 0x00, 0x60, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7c, 0x44, 0x40, 0x44, 0x40, 0x40, 0x4c, 0x44,
|
||||
0x10, 0x04, 0x50, 0x40, 0x44, 0x4c, 0x44, 0x40, 0x54, 0x50, 0x04, 0x10,
|
||||
0x44, 0x44, 0x54, 0x28, 0x10, 0x20, 0x00, 0x3c, 0x44, 0x40, 0x44, 0x7c,
|
||||
0x20, 0x44, 0x44, 0x10, 0x08, 0x70, 0x10, 0x54, 0x44, 0x44, 0x44, 0x44,
|
||||
0x40, 0x38, 0x10, 0x44, 0x44, 0x54, 0x10, 0x44, 0x10, 0x00, 0x64, 0x10,
|
||||
0x20, 0x04, 0x7c, 0x04, 0x44, 0x20, 0x44, 0x04, 0x10, 0x00, 0x7c, 0x14,
|
||||
0x20, 0x54, 0x00, 0x20, 0x04, 0x38, 0x10, 0x10, 0x00, 0x00, 0x20, 0x10,
|
||||
0x10, 0x10, 0x7c, 0x08, 0x10, 0x58, 0x40, 0x08, 0x04, 0x00, 0x00, 0x30,
|
||||
0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x44, 0x44, 0x44, 0x44, 0x40, 0x40, 0x44, 0x44, 0x10, 0x44, 0x48, 0x40,
|
||||
0x44, 0x44, 0x44, 0x40, 0x48, 0x48, 0x44, 0x10, 0x44, 0x28, 0x6c, 0x44,
|
||||
0x10, 0x40, 0x00, 0x44, 0x44, 0x40, 0x44, 0x40, 0x20, 0x3c, 0x44, 0x10,
|
||||
0x08, 0x48, 0x10, 0x54, 0x44, 0x44, 0x44, 0x44, 0x40, 0x04, 0x12, 0x4c,
|
||||
0x28, 0x54, 0x28, 0x3c, 0x20, 0x00, 0x44, 0x10, 0x40, 0x44, 0x08, 0x44,
|
||||
0x44, 0x20, 0x44, 0x08, 0x00, 0x00, 0x28, 0x78, 0x44, 0x48, 0x00, 0x10,
|
||||
0x08, 0x54, 0x10, 0x10, 0x00, 0x00, 0x40, 0x00, 0x10, 0x08, 0x00, 0x10,
|
||||
0x00, 0x40, 0x40, 0x04, 0x04, 0x00, 0x00, 0x30, 0x10, 0x18, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x78, 0x38, 0x78,
|
||||
0x7c, 0x40, 0x3c, 0x44, 0x38, 0x38, 0x44, 0x7c, 0x44, 0x44, 0x38, 0x40,
|
||||
0x34, 0x44, 0x38, 0x10, 0x38, 0x10, 0x44, 0x44, 0x10, 0x7c, 0x00, 0x3c,
|
||||
0x78, 0x3c, 0x3c, 0x3c, 0x20, 0x04, 0x44, 0x38, 0x48, 0x44, 0x38, 0x44,
|
||||
0x44, 0x38, 0x78, 0x3c, 0x40, 0x78, 0x0c, 0x34, 0x10, 0x6c, 0x44, 0x04,
|
||||
0x7c, 0x00, 0x38, 0x38, 0x7c, 0x38, 0x08, 0x38, 0x38, 0x20, 0x38, 0x70,
|
||||
0x10, 0x00, 0x28, 0x10, 0x00, 0x34, 0x00, 0x08, 0x10, 0x10, 0x00, 0x20,
|
||||
0x00, 0x10, 0x00, 0x00, 0x20, 0x04, 0x00, 0x20, 0x10, 0x3c, 0x70, 0x00,
|
||||
0x1c, 0x00, 0x7c, 0x1c, 0x10, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
GL4ProfilerDisplay::GL4ProfilerDisplay(WGLControl* control)
|
||||
: control_(control),
|
||||
program_(0),
|
||||
vao_(0),
|
||||
font_texture_(0),
|
||||
font_handle_(0),
|
||||
vertex_buffer_(MICROPROFILE_MAX_VERTICES * sizeof(Vertex) * 10, sizeof(Vertex)),
|
||||
draw_command_count_(0) {
|
||||
if (!SetupFont() || !SetupState() || !SetupShaders()) {
|
||||
// Hrm.
|
||||
assert_always();
|
||||
}
|
||||
|
||||
// Pass through mouse events.
|
||||
control->on_mouse_down.AddListener([](poly::ui::MouseEvent& e) {
|
||||
Profiler::OnMouseDown(e.button() == poly::ui::MouseEvent::Button::kLeft,
|
||||
e.button() == poly::ui::MouseEvent::Button::kRight);
|
||||
e.set_handled(true);
|
||||
});
|
||||
control->on_mouse_up.AddListener([](poly::ui::MouseEvent& e) {
|
||||
Profiler::OnMouseUp();
|
||||
e.set_handled(true);
|
||||
});
|
||||
control->on_mouse_move.AddListener([](poly::ui::MouseEvent& e) {
|
||||
Profiler::OnMouseMove(e.x(), e.y());
|
||||
e.set_handled(true);
|
||||
});
|
||||
control->on_mouse_wheel.AddListener([](poly::ui::MouseEvent& e) {
|
||||
Profiler::OnMouseWheel(e.x(), e.y(), -e.dy());
|
||||
e.set_handled(true);
|
||||
});
|
||||
|
||||
// Watch for toggle/mode keys and such.
|
||||
control->on_key_down.AddListener([](poly::ui::KeyEvent& e) {
|
||||
Profiler::OnKeyDown(e.key_code());
|
||||
e.set_handled(true);
|
||||
});
|
||||
control->on_key_up.AddListener([](poly::ui::KeyEvent& e) {
|
||||
Profiler::OnKeyUp(e.key_code());
|
||||
e.set_handled(true);
|
||||
});
|
||||
}
|
||||
|
||||
bool GL4ProfilerDisplay::SetupFont() {
|
||||
// Setup font lookup table.
|
||||
for (uint32_t i = 0; i < poly::countof(font_description_.char_offsets); ++i) {
|
||||
font_description_.char_offsets[i] = 206;
|
||||
}
|
||||
for (uint32_t i = 'A'; i <= 'Z'; ++i) {
|
||||
font_description_.char_offsets[i] = (i - 'A') * 8 + 1;
|
||||
}
|
||||
for (uint32_t i = 'a'; i <= 'z'; ++i) {
|
||||
font_description_.char_offsets[i] = (i - 'a') * 8 + 217;
|
||||
}
|
||||
for (uint32_t i = '0'; i <= '9'; ++i) {
|
||||
font_description_.char_offsets[i] = (i - '0') * 8 + 433;
|
||||
}
|
||||
for (uint32_t i = '!'; i <= '/'; ++i) {
|
||||
font_description_.char_offsets[i] = (i - '!') * 8 + 513;
|
||||
}
|
||||
for (uint32_t i = ':'; i <= '@'; ++i) {
|
||||
font_description_.char_offsets[i] = (i - ':') * 8 + 625 + 8;
|
||||
}
|
||||
for (uint32_t i = '['; i <= '_'; ++i) {
|
||||
font_description_.char_offsets[i] = (i - '[') * 8 + 681 + 8;
|
||||
}
|
||||
for (uint32_t i = '{'; i <= '~'; ++i) {
|
||||
font_description_.char_offsets[i] = (i - '{') * 8 + 721 + 8;
|
||||
}
|
||||
|
||||
// Unpack font bitmap into an RGBA texture.
|
||||
const int UNPACKED_SIZE = FONT_TEX_X * FONT_TEX_Y * 4;
|
||||
uint32_t unpacked[UNPACKED_SIZE];
|
||||
int idx = 0;
|
||||
int end = FONT_TEX_X * FONT_TEX_Y / 8;
|
||||
for (int i = 0; i < end; i++) {
|
||||
uint8_t b = profiler_font[i];
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
unpacked[idx++] = b & 0x80 ? 0xFFFFFFFFu : 0;
|
||||
b <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &font_texture_);
|
||||
glTextureParameteri(font_texture_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTextureParameteri(font_texture_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTextureParameteri(font_texture_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTextureParameteri(font_texture_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTextureStorage2D(font_texture_, 1, GL_RGBA8, FONT_TEX_X, FONT_TEX_Y);
|
||||
glTextureSubImage2D(font_texture_, 0, 0, 0, FONT_TEX_X, FONT_TEX_Y, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, unpacked);
|
||||
|
||||
font_handle_ = glGetTextureHandleARB(font_texture_);
|
||||
glMakeTextureHandleResidentARB(font_handle_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GL4ProfilerDisplay::SetupState() {
|
||||
if (!vertex_buffer_.Initialize()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GL4ProfilerDisplay::SetupShaders() {
|
||||
const std::string header =
|
||||
"\n\
|
||||
#version 450 \n\
|
||||
#extension GL_ARB_bindless_texture : require\n\
|
||||
#extension GL_ARB_explicit_uniform_location : require\n\
|
||||
#extension GL_ARB_shading_language_420pack : require\n\
|
||||
precision highp float; \n\
|
||||
precision highp int;\n\
|
||||
layout(std140, column_major) uniform;\n\
|
||||
layout(std430, column_major) buffer;\n\
|
||||
struct VertexData {\n\
|
||||
vec4 color; \n\
|
||||
vec2 uv; \n\
|
||||
};\n\
|
||||
";
|
||||
const std::string vertex_shader_source = header +
|
||||
"\n\
|
||||
layout(location = 0) uniform mat4 projection_matrix; \n\
|
||||
struct VertexFetch { \n\
|
||||
vec2 pos; \n\
|
||||
vec4 color; \n\
|
||||
vec2 uv; \n\
|
||||
}; \n\
|
||||
layout(location = 0) in VertexFetch vfetch; \n\
|
||||
layout(location = 0) out VertexData vtx; \n\
|
||||
void main() { \n\
|
||||
gl_Position = projection_matrix * vec4(vfetch.pos.xy, 0.0, 1.0); \n\
|
||||
vtx.color = vfetch.color; \n\
|
||||
vtx.uv = vfetch.uv; \n\
|
||||
} \n\
|
||||
";
|
||||
const std::string fragment_shader_source = header +
|
||||
"\n\
|
||||
layout(location = 1, bindless_sampler) uniform sampler2D font_texture; \n\
|
||||
layout(location = 2) uniform float font_height; \n\
|
||||
layout(location = 0) in VertexData vtx; \n\
|
||||
layout(location = 0) out vec4 oC; \n\
|
||||
void main() { \n\
|
||||
if (vtx.uv.x > 1.0) { \n\
|
||||
oC = vtx.color; \n\
|
||||
} else { \n\
|
||||
vec4 color = texture(font_texture, vtx.uv); \n\
|
||||
oC = color.rgba * vtx.color; \n\
|
||||
if (color.a < 0.5) { \n\
|
||||
vec4 c1 = texture(font_texture, vtx.uv + vec2(0.0, font_height)); \n\
|
||||
oC = vec4(0, 0, 0, c1.a); \n\
|
||||
} \n\
|
||||
} \n\
|
||||
} \n\
|
||||
";
|
||||
|
||||
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
const char* vertex_shader_source_ptr = vertex_shader_source.c_str();
|
||||
GLint vertex_shader_source_length = GLint(vertex_shader_source.size());
|
||||
glShaderSource(vertex_shader, 1, &vertex_shader_source_ptr,
|
||||
&vertex_shader_source_length);
|
||||
glCompileShader(vertex_shader);
|
||||
|
||||
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
const char* fragment_shader_source_ptr = fragment_shader_source.c_str();
|
||||
GLint fragment_shader_source_length = GLint(fragment_shader_source.size());
|
||||
glShaderSource(fragment_shader, 1, &fragment_shader_source_ptr,
|
||||
&fragment_shader_source_length);
|
||||
glCompileShader(fragment_shader);
|
||||
|
||||
program_ = glCreateProgram();
|
||||
glAttachShader(program_, vertex_shader);
|
||||
glAttachShader(program_, fragment_shader);
|
||||
glLinkProgram(program_);
|
||||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
|
||||
glProgramUniformHandleui64ARB(program_, 1, font_handle_);
|
||||
glProgramUniform1f(program_, 2, 1.0f / FONT_TEX_Y);
|
||||
|
||||
glCreateVertexArrays(1, &vao_);
|
||||
glEnableVertexArrayAttrib(vao_, 0);
|
||||
glVertexArrayAttribBinding(vao_, 0, 0);
|
||||
glVertexArrayAttribFormat(vao_, 0, 2, GL_FLOAT, GL_FALSE,
|
||||
offsetof(Vertex, x));
|
||||
glEnableVertexArrayAttrib(vao_, 1);
|
||||
glVertexArrayAttribBinding(vao_, 1, 0);
|
||||
glVertexArrayAttribFormat(vao_, 1, 4, GL_UNSIGNED_BYTE, GL_TRUE,
|
||||
offsetof(Vertex, color));
|
||||
glEnableVertexArrayAttrib(vao_, 2);
|
||||
glVertexArrayAttribBinding(vao_, 2, 0);
|
||||
glVertexArrayAttribFormat(vao_, 2, 2, GL_FLOAT, GL_FALSE,
|
||||
offsetof(Vertex, u));
|
||||
glVertexArrayVertexBuffer(vao_, 0, vertex_buffer_.handle(), 0,
|
||||
sizeof(Vertex));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GL4ProfilerDisplay::~GL4ProfilerDisplay() {
|
||||
vertex_buffer_.Shutdown();
|
||||
glMakeTextureHandleNonResidentARB(font_handle_);
|
||||
glDeleteTextures(1, &font_texture_);
|
||||
glDeleteVertexArrays(1, &vao_);
|
||||
glDeleteProgram(program_);
|
||||
}
|
||||
|
||||
uint32_t GL4ProfilerDisplay::width() const { return control_->width(); }
|
||||
|
||||
uint32_t GL4ProfilerDisplay::height() const { return control_->height(); }
|
||||
|
||||
void GL4ProfilerDisplay::Begin() {
|
||||
glEnablei(GL_BLEND, 0);
|
||||
glBlendFunci(0, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
float left = 0.0f;
|
||||
float right = float(width());
|
||||
float bottom = float(height());
|
||||
float top = 0.0f;
|
||||
float z_near = -1.0f;
|
||||
float z_far = 1.0f;
|
||||
float projection[16] = {0};
|
||||
projection[0] = 2.0f / (right - left);
|
||||
projection[5] = 2.0f / (top - bottom);
|
||||
projection[10] = -2.0f / (z_far - z_near);
|
||||
projection[12] = -(right + left) / (right - left);
|
||||
projection[13] = -(top + bottom) / (top - bottom);
|
||||
projection[14] = -(z_far + z_near) / (z_far - z_near);
|
||||
projection[15] = 1.0f;
|
||||
glProgramUniformMatrix4fv(program_, 0, 1, GL_FALSE, projection);
|
||||
|
||||
glUseProgram(program_);
|
||||
glBindVertexArray(vao_);
|
||||
}
|
||||
|
||||
void GL4ProfilerDisplay::End() {
|
||||
Flush();
|
||||
glUseProgram(0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
GL4ProfilerDisplay::Vertex* GL4ProfilerDisplay::BeginVertices(size_t count) {
|
||||
if (draw_command_count_ + 1 > kMaxCommands) {
|
||||
Flush();
|
||||
}
|
||||
current_allocation_ = vertex_buffer_.Acquire(sizeof(Vertex) * count);
|
||||
return reinterpret_cast<Vertex*>(current_allocation_.host_ptr);
|
||||
}
|
||||
|
||||
void GL4ProfilerDisplay::EndVertices(GLenum prim_type) {
|
||||
size_t vertex_count = current_allocation_.length / sizeof(Vertex);
|
||||
|
||||
if (false&&draw_command_count_ &&
|
||||
draw_commands_[draw_command_count_ - 1].prim_type == prim_type) {
|
||||
// Coalesce.
|
||||
auto& prev_command = draw_commands_[draw_command_count_ - 1];
|
||||
prev_command.vertex_count += vertex_count;
|
||||
} else {
|
||||
auto& command = draw_commands_[draw_command_count_++];
|
||||
command.prim_type = prim_type;
|
||||
command.vertex_offset = current_allocation_.offset / sizeof(Vertex);
|
||||
command.vertex_count = vertex_count;
|
||||
}
|
||||
|
||||
vertex_buffer_.Commit(std::move(current_allocation_));
|
||||
}
|
||||
|
||||
void GL4ProfilerDisplay::Flush() {
|
||||
if (!draw_command_count_) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < draw_command_count_; ++i) {
|
||||
glDrawArrays(draw_commands_[i].prim_type,
|
||||
GLint(draw_commands_[i].vertex_offset),
|
||||
GLsizei(draw_commands_[i].vertex_count));
|
||||
}
|
||||
draw_command_count_ = 0;
|
||||
vertex_buffer_.WaitUntilClean();
|
||||
}
|
||||
|
||||
void GL4ProfilerDisplay::DrawBox(int x0, int y0, int x1, int y1, uint32_t color,
|
||||
BoxType type) {
|
||||
if (type == BoxType::kFlat) {
|
||||
color =
|
||||
((color & 0xff) << 16) | ((color >> 16) & 0xff) | (0xff00ff00 & color);
|
||||
auto v = BeginVertices(6);
|
||||
Q0(v, x, (float)x0);
|
||||
Q0(v, y, (float)y0);
|
||||
Q0(v, color, color);
|
||||
Q0(v, u, 2.0f);
|
||||
Q0(v, v, 2.0f);
|
||||
Q1(v, x, (float)x1);
|
||||
Q1(v, y, (float)y0);
|
||||
Q1(v, color, color);
|
||||
Q1(v, u, 2.0f);
|
||||
Q1(v, v, 2.0f);
|
||||
Q2(v, x, (float)x1);
|
||||
Q2(v, y, (float)y1);
|
||||
Q2(v, color, color);
|
||||
Q2(v, u, 2.0f);
|
||||
Q2(v, v, 2.0f);
|
||||
Q3(v, x, (float)x0);
|
||||
Q3(v, y, (float)y1);
|
||||
Q3(v, color, color);
|
||||
Q3(v, u, 2.0f);
|
||||
Q3(v, v, 2.0f);
|
||||
EndVertices(GL_TRIANGLES);
|
||||
} else {
|
||||
uint32_t r = 0xff & (color >> 16);
|
||||
uint32_t g = 0xff & (color >> 8);
|
||||
uint32_t b = 0xff & color;
|
||||
uint32_t nMax = std::max(std::max(std::max(r, g), b), 30u);
|
||||
uint32_t nMin = std::min(std::min(std::min(r, g), b), 180u);
|
||||
|
||||
uint32_t r0 = 0xff & ((r + nMax) / 2);
|
||||
uint32_t g0 = 0xff & ((g + nMax) / 2);
|
||||
uint32_t b0 = 0xff & ((b + nMax) / 2);
|
||||
|
||||
uint32_t r1 = 0xff & ((r + nMin) / 2);
|
||||
uint32_t g1 = 0xff & ((g + nMin) / 2);
|
||||
uint32_t b1 = 0xff & ((b + nMin) / 2);
|
||||
uint32_t color0 = (r0 << 0) | (g0 << 8) | (b0 << 16) | (0xff000000 & color);
|
||||
uint32_t color1 = (r1 << 0) | (g1 << 8) | (b1 << 16) | (0xff000000 & color);
|
||||
auto v = BeginVertices(6);
|
||||
Q0(v, x, (float)x0);
|
||||
Q0(v, y, (float)y0);
|
||||
Q0(v, color, color0);
|
||||
Q0(v, u, 2.0f);
|
||||
Q0(v, v, 2.0f);
|
||||
Q1(v, x, (float)x1);
|
||||
Q1(v, y, (float)y0);
|
||||
Q1(v, color, color0);
|
||||
Q1(v, u, 3.0f);
|
||||
Q1(v, v, 2.0f);
|
||||
Q2(v, x, (float)x1);
|
||||
Q2(v, y, (float)y1);
|
||||
Q2(v, color, color1);
|
||||
Q2(v, u, 3.0f);
|
||||
Q2(v, v, 3.0f);
|
||||
Q3(v, x, (float)x0);
|
||||
Q3(v, y, (float)y1);
|
||||
Q3(v, color, color1);
|
||||
Q3(v, u, 2.0f);
|
||||
Q3(v, v, 3.0f);
|
||||
EndVertices(GL_TRIANGLES);
|
||||
}
|
||||
}
|
||||
|
||||
void GL4ProfilerDisplay::DrawLine2D(uint32_t count, float* vertices,
|
||||
uint32_t color) {
|
||||
if (!count || !vertices) {
|
||||
return;
|
||||
}
|
||||
auto v = BeginVertices(2 * (count - 1));
|
||||
color = 0xff000000 | ((color & 0xff) << 16) | (color & 0xff00ff00) |
|
||||
((color >> 16) & 0xff);
|
||||
for (uint32_t i = 0; i < count - 1; ++i) {
|
||||
v[0].x = vertices[i * 2];
|
||||
v[0].y = vertices[i * 2 + 1];
|
||||
v[0].color = color;
|
||||
v[0].u = 2.0f;
|
||||
v[0].v = 2.0f;
|
||||
v[1].x = vertices[(i + 1) * 2];
|
||||
v[1].y = vertices[(i + 1) * 2 + 1];
|
||||
v[1].color = color;
|
||||
v[1].u = 2.0f;
|
||||
v[1].v = 2.0f;
|
||||
v += 2;
|
||||
}
|
||||
EndVertices(GL_LINES);
|
||||
}
|
||||
|
||||
void GL4ProfilerDisplay::DrawText(int x, int y, uint32_t color,
|
||||
const char* text, size_t text_length) {
|
||||
const float fOffsetU = 5.0f / 1024.0f;
|
||||
float fX = (float)x;
|
||||
float fY = (float)y;
|
||||
float fY2 = fY + (MICROPROFILE_TEXT_HEIGHT + 1);
|
||||
|
||||
auto v = BeginVertices(6 * text_length);
|
||||
const char* pStr = text;
|
||||
color = 0xff000000 | ((color & 0xff) << 16) | (color & 0xff00) |
|
||||
((color >> 16) & 0xff);
|
||||
|
||||
for (size_t j = 0; j < text_length; ++j) {
|
||||
int16_t char_offset = font_description_.char_offsets[(int)*pStr++];
|
||||
float fOffset = char_offset / 1024.0f;
|
||||
Q0(v, x, fX);
|
||||
Q0(v, y, fY);
|
||||
Q0(v, color, color);
|
||||
Q0(v, u, fOffset);
|
||||
Q0(v, v, 0.0f);
|
||||
|
||||
Q1(v, x, fX + MICROPROFILE_TEXT_WIDTH);
|
||||
Q1(v, y, fY);
|
||||
Q1(v, color, color);
|
||||
Q1(v, u, fOffset + fOffsetU);
|
||||
Q1(v, v, 0.0f);
|
||||
|
||||
Q2(v, x, fX + MICROPROFILE_TEXT_WIDTH);
|
||||
Q2(v, y, fY2);
|
||||
Q2(v, color, color);
|
||||
Q2(v, u, fOffset + fOffsetU);
|
||||
Q2(v, v, 1.0f);
|
||||
|
||||
Q3(v, x, fX);
|
||||
Q3(v, y, fY2);
|
||||
Q3(v, color, color);
|
||||
Q3(v, u, fOffset);
|
||||
Q3(v, v, 1.0f);
|
||||
|
||||
fX += MICROPROFILE_TEXT_WIDTH + 1;
|
||||
v += 6;
|
||||
}
|
||||
|
||||
EndVertices(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
} // namespace gl4
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
Reference in New Issue
Block a user