Add double-buffered render target support to bgfx shader defs, nw

This commit is contained in:
therealmogminer@gmail.com 2016-03-09 02:51:02 +01:00
parent a20459a6a3
commit 47bdc0f254
14 changed files with 218 additions and 76 deletions

View File

@ -16,11 +16,8 @@
"targets": [
{ "name": "native",
"mode": "native",
"prescale": 1
},
{ "name": "native2",
"mode": "native",
"prescale": 1
"prescale": 1,
"doublebuffer": true
},
{ "name": "previous",
"mode": "native",
@ -31,8 +28,8 @@
{ "effect": "ratios",
"name": "Matrix Pass",
"disable_conditions": [
{ "type": "slider", "name": "adjustments", "value": false },
{ "type": "slider", "name": "ratio_amount", "value": 0 }
{ "type": "slider", "name": "adjustments", "value": 0 },
{ "type": "slider", "name": "ratio_amount", "value": 0.0 }
],
"uniforms": [
{ "uniform": "u_ratio_amount", "slider": "ratio_amount" },
@ -48,7 +45,7 @@
{ "effect": "tint",
"name": "Tint Pass",
"disable_conditions": [
{ "type": "slider", "name": "adjustments", "value": false }
{ "type": "slider", "name": "adjustments", "value": 0 }
],
"uniforms": [
{ "uniform": "u_tint", "slider": "tint" },
@ -57,7 +54,7 @@
"input": [
{ "sampler": "s_tex", "texture": "native" }
],
"output": "native2"
"output": "native"
},
{ "effect": "phosphor",
"name": "Phosphor Decay",
@ -70,7 +67,7 @@
{ "uniform": "u_phosphor", "slider": "phosphor" }
],
"input": [
{ "sampler": "s_tex", "texture": "native2" },
{ "sampler": "s_tex", "texture": "native" },
{ "sampler": "s_prev", "texture": "previous" }
],
"output": "native"

View File

@ -67,6 +67,11 @@ void bgfx_chain_entry::submit(render_primitive* prim, int view, texture_manager&
}
m_effect->submit(view, blend);
if (m_output != nullptr)
{
m_output->page_flip();
}
}
void bgfx_chain_entry::setup_view(int view, uint16_t screen_width, uint16_t screen_height)

View File

@ -76,6 +76,8 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, running_machine& m
assert(target_array[i].HasMember("name"));
assert(target_array[i]["name"].IsString());
uint32_t mode = uint32_t(get_enum_from_value(value, "mode", TARGET_STYLE_NATIVE, STYLE_NAMES, STYLE_COUNT));
bool bilinear = get_bool(target_array[i], "bilinear", false);
bool double_buffer = get_bool(target_array[i], "doublebuffer", false);
float prescalef = 1.0f;
float default_prescale = 1.0f;
@ -107,7 +109,7 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, running_machine& m
width *= prescale;
height *= prescale;
targets.create_target(target_array[i]["name"].GetString(), bgfx::TextureFormat::RGBA8, width, height, mode);
targets.create_target(target_array[i]["name"].GetString(), bgfx::TextureFormat::RGBA8, width, height, mode, double_buffer, bilinear);
}
}

View File

@ -25,12 +25,12 @@ bgfx_input_pair::bgfx_input_pair(int index, std::string sampler, std::string tex
void bgfx_input_pair::bind(bgfx_effect *effect, texture_manager& textures)
{
bgfx::setTexture(m_index, effect->uniform(m_sampler)->handle(), textures.texture(m_texture)->handle());
bgfx::setTexture(m_index, effect->uniform(m_sampler)->handle(), textures.handle(m_texture));
bgfx_uniform *size_uniform = effect->uniform("u_texsize");
if (size_uniform != nullptr)
{
float width = float(textures.texture(m_texture)->width());
float height = float(textures.texture(m_texture)->height());
float width = float(textures.provider(m_texture)->width());
float height = float(textures.provider(m_texture)->height());
float size[4] = { 1.0f / width, 1.0f / height, 0.0f, 0.0f };
size_uniform->set(reinterpret_cast<void *>(size), sizeof(float) * 4);
}

View File

@ -8,21 +8,91 @@
#include "target.h"
bgfx_target::bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, bool filter, uint32_t style)
: bgfx_texture(name, format, width, height, BGFX_TEXTURE_RT | BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | (filter ? 0 : (BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT)), nullptr)
bgfx_target::bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t style, bool double_buffer, bool filter)
: m_name(name)
, m_format(format)
, m_targets(nullptr)
, m_textures(nullptr)
, m_width(width)
, m_height(height)
, m_double_buffer(double_buffer)
, m_style(style)
, m_filter(filter)
, m_current_page(0)
, m_page_count(double_buffer ? 2 : 1)
{
m_target = bgfx::createFrameBuffer(1, &m_handle, false);
uint32_t wrap_mode = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP;
uint32_t filter_mode = filter ? 0 : (BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT);
m_textures = new bgfx::TextureHandle[m_page_count];
m_targets = new bgfx::FrameBufferHandle[m_page_count];
for (int page = 0; page < m_page_count; page++)
{
m_textures[page] = bgfx::createTexture2D(width, height, 1, format, wrap_mode | filter_mode | BGFX_TEXTURE_RT);
m_targets[page] = bgfx::createFrameBuffer(1, &m_textures[page], false);
}
}
bgfx_target::bgfx_target(std::string name, uint32_t width, uint32_t height, uint32_t style, void *handle)
: bgfx_texture(name, bgfx::TextureFormat::RGBA8, width, height, BGFX_TEXTURE_RT | BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT, nullptr)
, m_style(style)
bgfx_target::bgfx_target(void *handle, uint16_t width, uint16_t height)
: m_name("backbuffer")
, m_format(bgfx::TextureFormat::Unknown)
, m_targets(nullptr)
, m_textures(nullptr)
, m_width(width)
, m_height(height)
, m_double_buffer(false)
, m_style(TARGET_STYLE_CUSTOM)
, m_filter(false)
, m_current_page(0)
, m_page_count(0)
{
m_target = bgfx::createFrameBuffer(handle, width, height);
m_targets = new bgfx::FrameBufferHandle[1];
m_targets[0] = bgfx::createFrameBuffer(handle, width, height);
// No backing texture
}
bgfx_target::~bgfx_target()
{
bgfx::destroyFrameBuffer(m_target);
if (m_page_count > 0)
{
for (int page = 0; page < m_page_count; page++)
{
bgfx::destroyFrameBuffer(m_targets[page]);
bgfx::destroyTexture(m_textures[page]);
}
delete [] m_textures;
delete [] m_targets;
}
else
{
bgfx::destroyFrameBuffer(m_targets[0]);
delete [] m_targets;
}
}
void bgfx_target::page_flip()
{
if (m_double_buffer)
{
m_current_page = 1 - m_current_page;
}
}
bgfx::FrameBufferHandle bgfx_target::target()
{
return m_targets[m_current_page];
}
bgfx::TextureHandle bgfx_target::texture() const
{
if (m_double_buffer)
{
return m_textures[1 - m_current_page];
}
else
{
return m_textures[m_current_page];
}
}

View File

@ -11,7 +11,11 @@
#ifndef __DRAWBGFX_TARGET__
#define __DRAWBGFX_TARGET__
#include "texture.h"
#include <bgfx/bgfx.h>
#include <string>
#include "texturehandleprovider.h"
enum
{
@ -20,23 +24,46 @@ enum
TARGET_STYLE_CUSTOM
};
class bgfx_target : public bgfx_texture
class bgfx_target : public bgfx_texture_handle_provider
{
public:
bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, bool filter = false, uint32_t style = TARGET_STYLE_CUSTOM);
bgfx_target(std::string name, uint32_t width, uint32_t height, uint32_t style, void *handle);
bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t style, bool double_buffer, bool filter);
bgfx_target(void *handle, uint16_t width, uint16_t height);
virtual ~bgfx_target();
void page_flip();
// Getters
bgfx::FrameBufferHandle target() const { return m_target; }
uint32_t style() const { return m_style; }
bool filter() const { return m_filter; }
bgfx::FrameBufferHandle target();
bgfx::TextureFormat::Enum format() const { return m_format; }
std::string name() const { return m_name; }
bool double_buffered() const { return m_double_buffer; }
uint32_t style() const { return m_style; }
bool filter() const { return m_filter; }
// bgfx_texture_handle_provider
virtual uint16_t width() const override { return m_width; }
virtual uint16_t height() const override { return m_height; }
virtual bgfx::TextureHandle texture() const override;
virtual bool is_target() const override { return true; }
private:
bgfx::FrameBufferHandle m_target;
std::string m_name;
bgfx::TextureFormat::Enum m_format;
bgfx::FrameBufferHandle* m_targets;
bgfx::TextureHandle* m_textures;
uint16_t m_width;
uint16_t m_height;
bool m_double_buffer;
uint32_t m_style;
bool m_filter;
uint32_t m_current_page;
const uint32_t m_page_count;
};
#endif // __DRAWBGFX_TARGET__

View File

@ -25,21 +25,19 @@ target_manager::~target_manager()
m_targets.clear();
}
bgfx_target* target_manager::create_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, bool filter)
bgfx_target* target_manager::create_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, uint32_t style, bool double_buffer, bool filter)
{
bgfx_target* target = new bgfx_target(name, format, width, height, filter);
bgfx_target* target = new bgfx_target(name, format, width, height, style, double_buffer, filter);
m_targets[name] = target;
m_textures.add_texture(name, target);
m_textures.add_provider(name, target);
return target;
}
bgfx_target* target_manager::create_target(std::string name, void *handle, uint32_t width, uint32_t height)
bgfx_target* target_manager::create_backbuffer(void *handle, uint32_t width, uint32_t height)
{
bgfx_target* target = new bgfx_target(name, width, height, TARGET_STYLE_CUSTOM, handle);
m_targets[name] = target;
m_textures.add_texture(name, target);
bgfx_target* target = new bgfx_target(handle, width, height);
m_targets["backbuffer"] = target;
return target;
}
@ -71,7 +69,7 @@ void target_manager::update_guest_targets(uint16_t width, uint16_t height)
for (bgfx_target* target : to_resize)
{
m_targets[target->name()] = new bgfx_target(target->name(), target->format(), width, height, TARGET_STYLE_GUEST, target->filter());
m_targets[target->name()] = new bgfx_target(target->name(), target->format(), width, height, TARGET_STYLE_GUEST, target->double_buffered(), target->filter());
delete target;
}
}

View File

@ -28,8 +28,8 @@ public:
target_manager(texture_manager& textures) : m_textures(textures), m_guest_width(16), m_guest_height(16) { }
~target_manager();
bgfx_target* create_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, bool filter = false);
bgfx_target* create_target(std::string name, void *handle, uint32_t width, uint32_t height);
bgfx_target* create_target(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, uint32_t style, bool double_buffer, bool filter);
bgfx_target* create_backbuffer(void *handle, uint32_t width, uint32_t height);
void update_guest_targets(uint16_t width, uint16_t height);
@ -39,8 +39,6 @@ public:
uint16_t guest_height() const { return m_guest_height; }
private:
bgfx_target* create_target(std::string name);
std::map<std::string, bgfx_target*> m_targets;
texture_manager& m_textures;

View File

@ -10,7 +10,7 @@
#include "texture.h"
bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, uint32_t flags, void* data)
bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t flags, void* data)
: m_name(name)
, m_format(format)
, m_width(width)
@ -20,19 +20,19 @@ bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, u
bgfx::calcTextureSize(info, width, height, 1, false, 1, format);
if (data != nullptr)
{
m_handle = bgfx::createTexture2D(width, height, 1, format, flags, bgfx::copy(data, info.storageSize));
m_texture = bgfx::createTexture2D(width, height, 1, format, flags, bgfx::copy(data, info.storageSize));
}
else
{
m_handle = bgfx::createTexture2D(width, height, 1, format, flags);
m_texture = bgfx::createTexture2D(width, height, 1, format, flags);
const bgfx::Memory* memory = bgfx::alloc(info.storageSize);
memset(memory->data, 0, info.storageSize);
bgfx::updateTexture2D(m_handle, 0, 0, 0, width, height, memory, info.storageSize / height);
bgfx::updateTexture2D(m_texture, 0, 0, 0, width, height, memory, info.storageSize / height);
}
}
bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, const bgfx::Memory* data, uint32_t flags)
bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, const bgfx::Memory* data, uint32_t flags)
: m_name(name)
, m_format(format)
, m_width(width)
@ -40,10 +40,10 @@ bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, u
{
bgfx::TextureInfo info;
bgfx::calcTextureSize(info, width, height, 1, false, 1, format);
m_handle = bgfx::createTexture2D(width, height, 1, format, flags, data);
m_texture = bgfx::createTexture2D(width, height, 1, format, flags, data);
}
bgfx_texture::~bgfx_texture()
{
bgfx::destroyTexture(m_handle);
bgfx::destroyTexture(m_texture);
}

View File

@ -15,27 +15,31 @@
#include <string>
class bgfx_texture
#include "texturehandleprovider.h"
class bgfx_texture : public bgfx_texture_handle_provider
{
public:
bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, uint32_t flags, void* data);
bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, const bgfx::Memory* data, uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP);
bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t flags, void* data);
bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, const bgfx::Memory* data, uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP);
virtual ~bgfx_texture();
// Getters
std::string name() const { return m_name; }
bgfx::TextureFormat::Enum format() const { return m_format; }
uint32_t width() const { return m_width; }
uint32_t height() const { return m_height; }
bgfx::TextureHandle handle() const { return m_handle; }
virtual bool is_target() const { return false; }
// bgfx_texture_handle_provider
virtual uint16_t width() const override { return m_width; }
virtual uint16_t height() const override { return m_height; }
virtual bgfx::TextureHandle texture() const override { return m_texture; }
virtual bool is_target() const override { return false; }
protected:
std::string m_name;
bgfx::TextureFormat::Enum m_format;
uint32_t m_width;
uint32_t m_height;
bgfx::TextureHandle m_handle;
uint16_t m_width;
uint16_t m_height;
bgfx::TextureHandle m_texture;
};
#endif // __DRAWBGFX_TEXTURE__

View File

@ -0,0 +1,28 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
//============================================================
//
// texturehandleprovider.h
//
//============================================================
#pragma once
#ifndef __DRAWBGFX_TEXTURE_HANDLE_PROVIDER__
#define __DRAWBGFX_TEXTURE_HANDLE_PROVIDER__
#include <bgfx/bgfx.h>
class bgfx_texture_handle_provider
{
public:
virtual ~bgfx_texture_handle_provider() { }
// Getters
virtual bgfx::TextureHandle texture() const = 0;
virtual bool is_target() const = 0;
virtual uint16_t width() const = 0;
virtual uint16_t height() const = 0;
};
#endif // __DRAWBGFX_TEXTURE_HANDLE_PROVIDER__

View File

@ -16,7 +16,7 @@
texture_manager::~texture_manager()
{
for (std::pair<std::string, bgfx_texture*> texture : m_textures)
for (std::pair<std::string, bgfx_texture_handle_provider*> texture : m_textures)
{
if (texture.second != nullptr && !(texture.second)->is_target())
{
@ -26,9 +26,9 @@ texture_manager::~texture_manager()
m_textures.clear();
}
void texture_manager::add_texture(std::string name, bgfx_texture* texture)
void texture_manager::add_provider(std::string name, bgfx_texture_handle_provider* provider)
{
m_textures[name] = texture;
m_textures[name] = provider;
}
bgfx_texture* texture_manager::create_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, void* data, uint32_t flags)
@ -38,9 +38,20 @@ bgfx_texture* texture_manager::create_texture(std::string name, bgfx::TextureFor
return texture;
}
bgfx_texture* texture_manager::texture(std::string name)
bgfx::TextureHandle texture_manager::handle(std::string name)
{
std::map<std::string, bgfx_texture*>::iterator iter = m_textures.find(name);
std::map<std::string, bgfx_texture_handle_provider*>::iterator iter = m_textures.find(name);
if (iter != m_textures.end())
{
return (iter->second)->texture();
}
return BGFX_INVALID_HANDLE;
}
bgfx_texture_handle_provider* texture_manager::provider(std::string name)
{
std::map<std::string, bgfx_texture_handle_provider*>::iterator iter = m_textures.find(name);
if (iter != m_textures.end())
{
return iter->second;

View File

@ -19,6 +19,7 @@
#include <bgfx/bgfx.h>
class bgfx_texture_handle_provider;
class bgfx_texture;
class texture_manager {
@ -27,15 +28,16 @@ public:
~texture_manager();
bgfx_texture* create_texture(std::string name, bgfx::TextureFormat::Enum format, uint32_t width, uint32_t height, void* data = nullptr, uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP);
void add_texture(std::string name, bgfx_texture* texture);
void add_provider(std::string name, bgfx_texture_handle_provider* texture);
// Getters
bgfx_texture* texture(std::string name);
bgfx::TextureHandle handle(std::string name);
bgfx_texture_handle_provider* provider(std::string name);
private:
bgfx_texture* create_texture(std::string name);
std::map<std::string, bgfx_texture*> m_textures;
std::map<std::string, bgfx_texture_handle_provider*> m_textures;
};
#endif // __DRAWBGFX_TEXTURE_MANAGER__

View File

@ -143,9 +143,9 @@ int renderer_bgfx::create()
if (window().m_index != 0)
{
#ifdef OSD_WINDOWS
m_framebuffer = m_targets->create_target("backbuffer", window().m_hwnd, m_width[window().m_index], m_height[window().m_index]);
m_framebuffer = m_targets->create_backbuffer(window().m_hwnd, m_width[window().m_index], m_height[window().m_index]);
#else
m_framebuffer = m_targets->create_target("backbuffer", sdlNativeWindowHandle(window().sdl_window()), m_width[window().m_index], m_height[window().m_index]);
m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(window().sdl_window()), m_width[window().m_index], m_height[window().m_index]);
#endif
bgfx::touch(window().m_index);
}
@ -318,12 +318,12 @@ void renderer_bgfx::render_screen_quad(int view, render_primitive* prim)
tex_width, tex_height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base);
bgfx_texture *texture = new bgfx_texture("screen", bgfx::TextureFormat::RGBA8, tex_width, tex_height, mem);
m_textures->add_texture("screen", texture);
m_textures->add_provider("screen", texture);
m_targets->update_guest_targets(tex_width, tex_height);
m_screen_chain->process(prim, view, *m_textures, window().get_size().width(), window().get_size().height(), get_blend_state(PRIMFLAG_GET_BLENDMODE(prim->flags)));
m_textures->add_texture("screen", nullptr);
m_textures->add_provider("screen", nullptr);
delete texture;
}
@ -809,9 +809,9 @@ int renderer_bgfx::draw(int update)
bgfx::reset(window().m_main->get_size().width(), window().m_main->get_size().height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
delete m_framebuffer;
#ifdef OSD_WINDOWS
m_framebuffer = m_targets->create_target("backbuffer", window().m_hwnd, m_width[index], m_height[index]);
m_framebuffer = m_targets->create_backbuffer(window().m_hwnd, m_width[index], m_height[index]);
#else
m_framebuffer = m_targets->create_target("backbuffer", sdlNativeWindowHandle(window().sdl_window()), m_width[index], m_height[index]);
m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(window().sdl_window()), m_width[index], m_height[index]);
#endif
bgfx::setViewFrameBuffer(index, m_framebuffer->target());
m_dimensions = osd_dim(m_width[index], m_height[index]);
@ -872,7 +872,7 @@ int renderer_bgfx::draw(int update)
if (status != BUFFER_EMPTY)
{
bgfx::setVertexBuffer(&buffer);
bgfx::setTexture(0, m_gui_effect[blend]->uniform("s_tex")->handle(), m_texture_cache->handle());
bgfx::setTexture(0, m_gui_effect[blend]->uniform("s_tex")->handle(), m_texture_cache->texture());
m_gui_effect[blend]->submit(index);
}
@ -1029,7 +1029,7 @@ void renderer_bgfx::process_atlas_packs(std::vector<std::vector<rectangle_packer
}
m_hash_to_entry[rect.hash()] = rect;
const bgfx::Memory* mem = mame_texture_data_to_bgfx_texture_data(rect.format(), rect.width(), rect.height(), rect.rowpixels(), rect.palette(), rect.base());
bgfx::updateTexture2D(m_texture_cache->handle(), 0, rect.x(), rect.y(), rect.width(), rect.height(), mem);
bgfx::updateTexture2D(m_texture_cache->texture(), 0, rect.x(), rect.y(), rect.width(), rect.height(), mem);
}
}
}