-bgfx: Abstracted some view-related functions into bgfx_view class, nw

This commit is contained in:
mooglyguy 2018-01-05 03:21:10 +01:00
parent 583db889a4
commit 7f3f8fd245
5 changed files with 214 additions and 111 deletions

View File

@ -207,6 +207,7 @@ function osdmodulesbuild()
MAME_DIR .. "src/osd/modules/render/bgfx/uniformreader.cpp",
MAME_DIR .. "src/osd/modules/render/bgfx/valueuniform.cpp",
MAME_DIR .. "src/osd/modules/render/bgfx/valueuniformreader.cpp",
MAME_DIR .. "src/osd/modules/render/bgfx/view.cpp",
MAME_DIR .. "src/osd/modules/render/bgfx/writereader.cpp",
}
includedirs {

View File

@ -0,0 +1,64 @@
#include "emu.h"
#include "window.h"
#include "rendutil.h"
#include "../drawbgfx.h"
#include <bx/math.h>
#include <bgfx/bgfx.h>
#include <bgfx/platform.h>
#include "target.h"
#include "view.h"
void bgfx_view::update() {
std::shared_ptr<osd_window> win = m_renderer->assert_window();
const uint32_t window_index = win->m_index;
const uint32_t width = m_renderer->get_window_width(window_index);
const uint32_t height = m_renderer->get_window_height(window_index);
if (window_index != m_window_index)
m_window_index = window_index;
if (width != m_view_width)
m_view_width = width;
if (height != m_view_height)
m_view_height = height;
}
void bgfx_ortho_view::setup() {
if (m_window_index != 0)
{
bgfx::setViewFrameBuffer(m_index, m_backbuffer->target());
}
bgfx::setViewRect(m_index, 0, 0, m_view_width, m_view_height);
while ((m_index + 1) > m_seen_views.size())
{
m_seen_views.push_back(false);
}
if (!m_seen_views[m_index])
{
m_seen_views[m_index] = true;
uint16_t flags = 0;
flags |= (m_do_clear_color ? BGFX_CLEAR_COLOR : 0);
flags |= (m_do_clear_depth ? BGFX_CLEAR_DEPTH : 0);
flags |= (m_do_clear_stencil ? BGFX_CLEAR_STENCIL : 0);
bgfx::setViewClear(m_index, flags, m_clear_color, m_clear_depth, m_clear_stencil);
bgfx::setViewMode(m_index, bgfx::ViewMode::Sequential);
}
setup_matrices();
}
void bgfx_ortho_view::setup_matrices() {
float proj[16];
float view[16];
const bgfx::Caps* caps = bgfx::getCaps();
bx::mtxIdentity(view);
bx::mtxOrtho(proj, 0.0f, m_view_width, m_view_height, 0.0f, m_z_near, m_z_far, 0.0f, caps->homogeneousDepth);
bgfx::setViewTransform(m_index, view, proj);
}

View File

@ -0,0 +1,68 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
#pragma once
#include "window.h"
class renderer_bgfx;
class bgfx_target;
class bgfx_view {
public:
bgfx_view(renderer_bgfx *renderer, uint32_t index, bgfx_target *backbuffer, std::vector<uint32_t> &seen_views)
: m_renderer(renderer)
, m_index(index)
, m_backbuffer(backbuffer)
, m_seen_views(seen_views)
, m_window_index(UINT_MAX)
, m_view_width(0)
, m_view_height(0)
, m_z_near(0.0f)
, m_z_far(100.0f)
, m_clear_color(0)
, m_clear_depth(1.0f)
, m_clear_stencil(0)
, m_do_clear_color(true)
, m_do_clear_depth(true)
, m_do_clear_stencil(false) {
}
virtual ~bgfx_view() { }
void update();
void set_backbuffer(bgfx_target *backbuffer) { m_backbuffer = backbuffer; }
void set_index(uint32_t index) { m_index = index; }
uint32_t get_index() const { return m_index; }
virtual void setup() = 0;
virtual void setup_matrices() = 0;
protected:
renderer_bgfx *m_renderer;
uint32_t m_index;
bgfx_target *m_backbuffer;
std::vector<uint32_t> &m_seen_views;
uint32_t m_window_index;
uint32_t m_view_width;
uint32_t m_view_height;
float m_z_near;
float m_z_far;
uint32_t m_clear_color;
float m_clear_depth;
uint8_t m_clear_stencil;
bool m_do_clear_color;
bool m_do_clear_depth;
bool m_do_clear_stencil;
};
class bgfx_ortho_view : public bgfx_view {
public:
bgfx_ortho_view(renderer_bgfx *renderer, uint32_t index, bgfx_target *backbuffer, std::vector<uint32_t> &seen_views) : bgfx_view(renderer, index, backbuffer, seen_views) { }
void setup() override;
void setup_matrices() override;
};

View File

@ -43,6 +43,7 @@
#include "bgfx/uniform.h"
#include "bgfx/slider.h"
#include "bgfx/target.h"
#include "bgfx/view.h"
#include "imgui/imgui.h"
@ -80,8 +81,17 @@ uint32_t renderer_bgfx::s_current_view = 0;
renderer_bgfx::renderer_bgfx(std::shared_ptr<osd_window> w)
: osd_renderer(w, FLAG_NONE)
, m_options(downcast<osd_options &>(w->machine().options()))
, m_framebuffer(nullptr)
, m_texture_cache(nullptr)
, m_dimensions(0, 0)
, m_textures(nullptr)
, m_targets(nullptr)
, m_shaders(nullptr)
, m_effects(nullptr)
, m_chains(nullptr)
, m_ortho_view(nullptr)
, m_max_view(0)
, m_avi_view(nullptr)
, m_avi_writer(nullptr)
, m_avi_target(nullptr)
{
@ -107,6 +117,7 @@ renderer_bgfx::~renderer_bgfx()
delete m_avi_writer;
delete [] m_avi_data;
delete m_avi_view;
}
// Cleanup.
@ -206,7 +217,7 @@ IInspectable* AsInspectable(Platform::Agile<Windows::UI::Core::CoreWindow> win)
int renderer_bgfx::create()
{
// create renderer
auto win = assert_window();
std::shared_ptr<osd_window> win = assert_window();
osd_dim wdim = win->get_size();
m_width[win->m_index] = wdim.width();
m_height[win->m_index] = wdim.height();
@ -284,6 +295,10 @@ int renderer_bgfx::create()
m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()), m_width[win->m_index], m_height[win->m_index]);
#endif
bgfx::touch(win->m_index);
if (m_ortho_view) {
m_ortho_view->set_backbuffer(m_framebuffer);
}
}
// Create program from shaders.
@ -323,7 +338,8 @@ int renderer_bgfx::create()
void renderer_bgfx::record()
{
auto win = assert_window();
std::shared_ptr<osd_window> win = assert_window();
if (win->m_index > 0)
{
return;
@ -342,12 +358,19 @@ void renderer_bgfx::record()
m_targets->destroy_target("avibuffer0");
m_avi_target = nullptr;
bgfx::destroy(m_avi_texture);
delete m_avi_view;
m_avi_view = nullptr;
}
else
{
m_avi_writer->record(m_options.bgfx_avi_name());
m_avi_target = m_targets->create_target("avibuffer", bgfx::TextureFormat::RGBA8, m_width[0], m_height[0], TARGET_STYLE_CUSTOM, false, true, 1, 0);
m_avi_texture = bgfx::createTexture2D(m_width[0], m_height[0], false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_BLIT_DST | BGFX_TEXTURE_READ_BACK);
if (m_avi_view == nullptr)
{
m_avi_view = new bgfx_ortho_view(this, 10, m_avi_target, m_seen_views);
}
}
}
@ -476,16 +499,17 @@ void renderer_bgfx::render_post_screen_quad(int view, render_primitive* prim, bg
uint32_t blend = PRIMFLAG_GET_BLENDMODE(prim->flags);
bgfx::setVertexBuffer(0,buffer);
bgfx::setTexture(0, m_screen_effect[blend]->uniform("s_tex")->handle(), m_targets->target(screen, "output")->texture(), texture_flags);
m_screen_effect[blend]->submit(view);
m_screen_effect[blend]->submit(m_ortho_view->get_index());
}
void renderer_bgfx::render_avi_quad()
{
m_avi_view->set_index(s_current_view);
m_avi_view->setup();
bgfx::setViewRect(s_current_view, 0, 0, m_width[0], m_height[0]);
bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
setup_matrices(s_current_view, false);
bgfx::TransientVertexBuffer buffer;
bgfx::allocTransientVertexBuffer(&buffer, 6, ScreenVertex::ms_decl);
ScreenVertex* vertices = reinterpret_cast<ScreenVertex*>(buffer.data);
@ -545,7 +569,7 @@ void renderer_bgfx::render_textured_quad(render_primitive* prim, bgfx::Transient
uint32_t blend = PRIMFLAG_GET_BLENDMODE(prim->flags);
bgfx::setVertexBuffer(0,buffer);
bgfx::setTexture(0, effects[blend]->uniform("s_tex")->handle(), texture);
effects[blend]->submit(m_ui_view);
effects[blend]->submit(m_ortho_view->get_index());
bgfx::destroy(texture);
}
@ -760,11 +784,14 @@ uint32_t renderer_bgfx::u32Color(uint32_t r, uint32_t g, uint32_t b, uint32_t a
int renderer_bgfx::draw(int update)
{
auto win = assert_window();
std::shared_ptr<osd_window> win = assert_window();
int window_index = win->m_index;
m_seen_views.clear();
m_ui_view = -1;
if (m_ortho_view) {
m_ortho_view->set_index(UINT_MAX);
}
osd_dim wdim = win->get_size();
m_width[window_index] = wdim.width();
@ -831,7 +858,7 @@ int renderer_bgfx::draw(int update)
{
bgfx::setVertexBuffer(0,&buffer);
bgfx::setTexture(0, m_gui_effect[blend]->uniform("s_tex")->handle(), m_texture_cache->texture());
m_gui_effect[blend]->submit(m_ui_view);
m_gui_effect[blend]->submit(m_ortho_view->get_index());
}
if (status != BUFFER_DONE && status != BUFFER_PRE_FLUSH)
@ -885,7 +912,7 @@ void renderer_bgfx::update_recording()
void renderer_bgfx::add_audio_to_recording(const int16_t *buffer, int samples_this_frame)
{
auto win = assert_window();
std::shared_ptr<osd_window> win = assert_window();
if (m_avi_writer != nullptr && m_avi_writer->recording() && win->m_index == 0)
{
m_avi_writer->audio_frame(buffer, samples_this_frame);
@ -894,7 +921,7 @@ void renderer_bgfx::add_audio_to_recording(const int16_t *buffer, int samples_th
bool renderer_bgfx::update_dimensions()
{
auto win = assert_window();
std::shared_ptr<osd_window> win = assert_window();
const uint32_t window_index = win->m_index;
const uint32_t width = m_width[window_index];
@ -924,6 +951,7 @@ bool renderer_bgfx::update_dimensions()
m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()), width, height);
#endif
m_ortho_view->set_backbuffer(m_framebuffer);
bgfx::setViewFrameBuffer(s_current_view, m_framebuffer->target());
bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
bgfx::setViewMode(s_current_view, bgfx::ViewMode::Sequential);
@ -935,84 +963,16 @@ bool renderer_bgfx::update_dimensions()
return false;
}
void renderer_bgfx::setup_view(uint32_t view_index, bool screen)
void renderer_bgfx::setup_ortho_view()
{
auto win = assert_window();
const uint32_t window_index = win->m_index;
const uint32_t width = m_width[window_index];
const uint32_t height = m_height[window_index];
if (window_index != 0)
if (!m_ortho_view)
{
bgfx::setViewFrameBuffer(view_index, m_framebuffer->target());
m_ortho_view = new bgfx_ortho_view(this, s_current_view, m_framebuffer, m_seen_views);
}
bgfx::setViewRect(view_index, 0, 0, width, height);
#if SCENE_VIEW
if (view_index == m_max_view)
{
#else
while ((view_index + 1) > m_seen_views.size())
{
m_seen_views.push_back(false);
}
if (!m_seen_views[view_index])
{
m_seen_views[view_index] = true;
#endif
if (m_avi_writer != nullptr && m_avi_writer->recording() && win->m_index == 0)
{
bgfx::setViewFrameBuffer(view_index, m_avi_target->target());
}
bgfx::setViewClear(view_index, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
bgfx::setViewMode(s_current_view, bgfx::ViewMode::Sequential);
}
setup_matrices(view_index, screen);
}
void renderer_bgfx::setup_matrices(uint32_t view_index, bool screen)
{
auto win = assert_window();
const uint32_t window_index = win->m_index;
const uint32_t width = m_width[window_index];
const uint32_t height = m_height[window_index];
float proj[16];
float view[16];
const bgfx::Caps* caps = bgfx::getCaps();
if (screen)
{
static float offset = 0.0f;
offset += 0.5f;
float up[3] = { 0.0f, -1.0f, 0.0f };
float cam_z = width * 0.5f * (float(height) / float(width));
cam_z *= 1.05f;
float eye_height = height * 0.5f * 1.05f;
float at[3] = { width * 0.5f, height * 0.5f, 0.0f };
float eye[3] = { width * 0.5f, eye_height, cam_z };
bx::mtxLookAt(view, eye, at, up);
bx::mtxProj(proj, 90.0f, float(width) / float(height), 0.1f, 5000.0f, bgfx::getCaps()->homogeneousDepth);
}
else
{
bx::mtxIdentity(view);
bx::mtxOrtho(proj, 0.0f, width, height, 0.0f, 0.0f, 100.0f, 0.0f, caps->homogeneousDepth);
}
bgfx::setViewTransform(view_index, view, proj);
}
void renderer_bgfx::init_ui_view()
{
if (m_ui_view < 0)
{
m_ui_view = s_current_view;
setup_view(m_ui_view, false);
m_ortho_view->update();
if (m_ortho_view->get_index() == UINT_MAX) {
m_ortho_view->set_index(s_current_view);
m_ortho_view->setup();
s_current_view++;
}
}
@ -1027,7 +987,7 @@ renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(bool atlas_valid,
switch ((*prim)->type)
{
case render_primitive::LINE:
init_ui_view();
setup_ortho_view();
put_packed_line(*prim, (ScreenVertex*)buffer->data + vertices);
vertices += 30;
break;
@ -1035,7 +995,7 @@ renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(bool atlas_valid,
case render_primitive::QUAD:
if ((*prim)->texture.base == nullptr)
{
init_ui_view();
setup_ortho_view();
put_packed_quad(*prim, WHITE_HASH, (ScreenVertex*)buffer->data + vertices);
vertices += 6;
}
@ -1044,7 +1004,7 @@ renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(bool atlas_valid,
const uint32_t hash = get_texture_hash(*prim);
if (atlas_valid && (*prim)->packable(PACKABLE_SIZE) && hash != 0 && m_hash_to_entry[hash].hash())
{
init_ui_view();
setup_ortho_view();
put_packed_quad(*prim, hash, (ScreenVertex*)buffer->data + vertices);
vertices += 6;
}
@ -1061,16 +1021,15 @@ renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(bool atlas_valid,
setup_view(s_current_view, true);
render_post_screen_quad(s_current_view, *prim, buffer, screen);
s_current_view++;
m_ui_view = -1;
#else
init_ui_view();
render_post_screen_quad(m_ui_view, *prim, buffer, screen);
setup_ortho_view();
render_post_screen_quad(m_ortho_view->get_index(), *prim, buffer, screen);
#endif
return BUFFER_SCREEN;
}
else
{
init_ui_view();
setup_ortho_view();
render_textured_quad(*prim, buffer);
return BUFFER_EMPTY;
}
@ -1185,7 +1144,7 @@ bool renderer_bgfx::check_for_dirty_atlas()
{
bool atlas_dirty = false;
auto win = assert_window();
std::shared_ptr<osd_window> win = assert_window();
std::map<uint32_t, rectangle_packer::packable_rectangle> acquired_infos;
for (render_primitive &prim : *win->m_primlist)
{
@ -1277,3 +1236,12 @@ void renderer_bgfx::set_sliders_dirty()
{
m_sliders_dirty = true;
}
uint32_t renderer_bgfx::get_window_width(uint32_t index) const {
return m_width[index];
}
uint32_t renderer_bgfx::get_window_height(uint32_t index) const {
return m_height[index];
}

View File

@ -26,6 +26,7 @@ class bgfx_texture;
class bgfx_effect;
class bgfx_target;
class bgfx_chain;
class bgfx_view;
class osd_options;
class avi_write;
@ -54,6 +55,9 @@ public:
virtual void record() override;
virtual void toggle_fsfx() override { }
uint32_t get_window_width(uint32_t index) const;
uint32_t get_window_height(uint32_t index) const;
virtual render_primitive_list *get_primitives() override
{
auto win = try_getwindow();
@ -85,10 +89,7 @@ private:
bool update_dimensions();
void setup_view(uint32_t view_index, bool screen);
void init_ui_view();
void setup_matrices(uint32_t view_index, bool screen);
void setup_ortho_view();
void allocate_buffer(render_primitive *prim, uint32_t blend, bgfx::TransientVertexBuffer *buffer);
enum buffer_status
@ -120,20 +121,20 @@ private:
osd_options& m_options;
bgfx_target* m_framebuffer;
bgfx_texture* m_texture_cache;
bgfx_target *m_framebuffer;
bgfx_texture *m_texture_cache;
// Original display_mode
osd_dim m_dimensions;
texture_manager* m_textures;
target_manager* m_targets;
shader_manager* m_shaders;
effect_manager* m_effects;
chain_manager* m_chains;
texture_manager *m_textures;
target_manager *m_targets;
shader_manager *m_shaders;
effect_manager *m_effects;
chain_manager *m_chains;
bgfx_effect* m_gui_effect[4];
bgfx_effect* m_screen_effect[4];
bgfx_effect *m_gui_effect[4];
bgfx_effect *m_screen_effect[4];
std::vector<uint32_t> m_seen_views;
std::map<uint32_t, rectangle_packer::packed_rectangle> m_hash_to_entry;
@ -143,14 +144,15 @@ private:
uint32_t m_width[16];
uint32_t m_height[16];
uint32_t m_white[16*16];
int32_t m_ui_view;
bgfx_view *m_ortho_view;
uint32_t m_max_view;
avi_write* m_avi_writer;
bgfx_target* m_avi_target;
bgfx_view *m_avi_view;
avi_write *m_avi_writer;
bgfx_target *m_avi_target;
bgfx::TextureHandle m_avi_texture;
bitmap_rgb32 m_avi_bitmap;
uint8_t* m_avi_data;
uint8_t *m_avi_data;
static const uint16_t CACHE_SIZE;
static const uint32_t PACKABLE_SIZE;