-bgfx: Improved rendering with artwork by 5-10x or more. [Ryan Holtz]

This commit is contained in:
mooglyguy 2018-08-26 16:26:22 +02:00
parent dd64cdceee
commit cd3cbf5603
9 changed files with 130 additions and 32 deletions

View File

@ -323,7 +323,8 @@ render_texture::render_texture()
m_next(nullptr),
m_bitmap(nullptr),
m_format(TEXFORMAT_ARGB32),
m_osddata(~0L),
m_id(~0ULL),
m_old_id(~0ULL),
m_scaler(nullptr),
m_param(nullptr),
m_curseq(0)
@ -357,7 +358,8 @@ void render_texture::reset(render_manager &manager, texture_scaler_func scaler,
m_scaler = scaler;
m_param = param;
}
m_osddata = ~0L;
m_old_id = m_id;
m_id = ~0L;
}
@ -447,7 +449,10 @@ void render_texture::get_scaled(u32 dwidth, u32 dheight, render_texinfo &texinfo
if (dwidth < 1) dwidth = 1;
if (dheight < 1) dheight = 1;
texinfo.osddata = m_osddata;
texinfo.unique_id = m_id;
texinfo.old_id = m_old_id;
if (m_old_id != ~0ULL)
m_old_id = ~0ULL;
// are we scaler-free? if so, just return the source bitmap
if (m_scaler == nullptr || (m_bitmap != nullptr && swidth == dwidth && sheight == dheight))
@ -617,8 +622,10 @@ void render_container::set_overlay(bitmap_argb32 *bitmap)
m_overlaybitmap = bitmap;
if (m_overlaybitmap != nullptr)
{
printf("Allocating overlay\n");
m_overlaytexture = m_manager.texture_alloc(render_container::overlay_scale);
m_overlaytexture->set_bitmap(*bitmap, bitmap->cliprect(), TEXFORMAT_ARGB32);
printf("Done allocating overlay\n");
}
}
@ -2964,6 +2971,7 @@ render_manager::render_manager(running_machine &machine)
: m_machine(machine),
m_ui_target(nullptr),
m_live_textures(0),
m_texture_id(0),
m_ui_container(global_alloc(render_container(*this)))
{
// register callbacks
@ -3128,6 +3136,8 @@ render_texture *render_manager::texture_alloc(texture_scaler_func scaler, void *
// allocate a new texture and reset it
render_texture *tex = m_texture_allocator.alloc();
tex->reset(*this, scaler, param);
tex->set_id(m_texture_id);
m_texture_id++;
m_live_textures++;
return tex;
}

View File

@ -215,7 +215,8 @@ struct render_texinfo
u32 width; // width of the image
u32 height; // height of the image
u32 seqid; // sequence ID
u64 osddata; // aux data to pass to osd
u64 unique_id; // unique identifier to pass to osd
u64 old_id; // previously allocated id, if applicable
const rgb_t * palette; // palette for PALETTE16 textures, bcg lookup table for RGB32/YUY16
};
@ -441,8 +442,8 @@ public:
// configure the texture bitmap
void set_bitmap(bitmap_t &bitmap, const rectangle &sbounds, texture_format format);
// set any necessary aux data
void set_osd_data(u64 data) { m_osddata = data; }
// set a unique identifier
void set_id(u64 id) { m_old_id = m_id; m_id = id; }
// generic high-quality bitmap scaler
static void hq_scale(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param);
@ -467,7 +468,8 @@ private:
bitmap_t * m_bitmap; // pointer to the original bitmap
rectangle m_sbounds; // source bounds within the bitmap
texture_format m_format; // format of the texture data
u64 m_osddata; // aux data to pass to osd
u64 m_id; // unique id to pass to osd
u64 m_old_id; // previous id, if applicable
// scaling state (ARGB32 only)
texture_scaler_func m_scaler; // scaling callback
@ -1181,6 +1183,7 @@ private:
// texture lists
u32 m_live_textures; // number of live textures
u64 m_texture_id; // rolling texture ID counter
fixed_allocator<render_texture> m_texture_allocator;// texture allocator
// containers for the UI and for screens

View File

@ -764,9 +764,9 @@ void screen_device::device_start()
// allocate raw textures
m_texture[0] = machine().render().texture_alloc();
m_texture[0]->set_osd_data(u64((m_unique_id << 1) | 0));
m_texture[0]->set_id(u64(m_unique_id) << 57);
m_texture[1] = machine().render().texture_alloc();
m_texture[1]->set_osd_data(u64((m_unique_id << 1) | 1));
m_texture[1]->set_id((u64(m_unique_id) << 57) | 1);
// configure the default cliparea
render_container::user_settings settings;

View File

@ -11,10 +11,9 @@
#include <bgfx/bgfx.h>
#include "emu.h"
#include "texturemanager.h"
#include "texture.h"
#include "bgfxutil.h"
#include "rendutil.h"
#include "modules/render/copyutil.h"
@ -28,6 +27,12 @@ texture_manager::~texture_manager()
}
}
m_textures.clear();
for (std::pair<uint64_t, sequenced_handle> mame_texture : m_mame_textures)
{
bgfx::destroy(mame_texture.second.handle);
}
m_mame_textures.clear();
}
void texture_manager::add_provider(std::string name, bgfx_texture_handle_provider* provider)
@ -85,6 +90,75 @@ bgfx_texture* texture_manager::create_png_texture(std::string path, std::string
return texture;
}
bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t format, int width, int height
, int rowpixels, const rgb_t *palette, void *base, uint32_t seqid, uint32_t flags, uint64_t key, uint64_t old_key)
{
bgfx::TextureHandle handle = BGFX_INVALID_HANDLE;
if (old_key != ~0ULL)
{
std::map<uint64_t, sequenced_handle>::iterator iter = m_mame_textures.find(old_key);
if (iter != m_mame_textures.end())
{
handle = iter->second.handle;
if (handle.idx == bgfx::kInvalidHandle)
return handle;
if (iter->second.width == width && iter->second.height == height)
{
// Size matches, so let's just swap the old handle into the new location
m_mame_textures[key] = { handle, seqid, width, height };
m_mame_textures[old_key] = { BGFX_INVALID_HANDLE, 0, 0, 0 };
if (iter->second.seqid == seqid)
{
// Everything matches, just return the existing handle
return handle;
}
else
{
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(format, width, height, rowpixels, palette, base);
bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)width, (uint16_t)height, mem);
return handle;
}
}
bgfx::destroy(handle);
m_mame_textures[old_key] = { BGFX_INVALID_HANDLE, 0, 0, 0 };
}
}
else
{
std::map<uint64_t, sequenced_handle>::iterator iter = m_mame_textures.find(key);
if (iter != m_mame_textures.end())
{
handle = iter->second.handle;
if (handle.idx == bgfx::kInvalidHandle)
return handle;
if (iter->second.width == width && iter->second.height == height)
{
if (iter->second.seqid == seqid)
{
return handle;
}
else
{
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(format, width, height, rowpixels, palette, base);
bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)width, (uint16_t)height, mem);
return handle;
}
}
bgfx::destroy(handle);
}
}
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(format, width, height, rowpixels, palette, base);
handle = bgfx::createTexture2D(width, height, false, 1, bgfx::TextureFormat::RGBA8, flags, nullptr);
bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)width, (uint16_t)height, mem);
m_mame_textures[key] = { handle, seqid, width, height };
return handle;
}
bgfx::TextureHandle texture_manager::handle(std::string name)
{
bgfx::TextureHandle handle = BGFX_INVALID_HANDLE;

View File

@ -11,8 +11,10 @@
#pragma once
#ifndef __DRAWBGFX_TEXTURE_MANAGER__
#define __DRAWBGFX_TEXTURE_MANAGER__
#ifndef DRAWBGFX_TEXTURE_MANAGER
#define DRAWBGFX_TEXTURE_MANAGER
#include "emu.h"
#include <map>
#include <string>
@ -31,6 +33,8 @@ public:
bgfx_texture* create_png_texture(std::string path, std::string file_name, std::string texture_name, uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP, uint32_t screen = -1);
void add_provider(std::string name, bgfx_texture_handle_provider* texture);
void remove_provider(std::string name, bool delete_provider = false);
bgfx::TextureHandle create_or_update_mame_texture(uint32_t format, int width, int height
, int rowpixels, const rgb_t *palette, void *base, uint32_t seqid, uint32_t flags, uint64_t key, uint64_t old_key);
// Getters
bgfx::TextureHandle handle(std::string name);
@ -39,7 +43,16 @@ public:
private:
bgfx_texture* create_texture(std::string name);
struct sequenced_handle
{
bgfx::TextureHandle handle;
uint32_t seqid;
int width;
int height;
};
std::map<std::string, bgfx_texture_handle_provider*> m_textures;
std::map<uint64_t, sequenced_handle> m_mame_textures;
};
#endif // __DRAWBGFX_TEXTURE_MANAGER__
#endif // DRAWBGFX_TEXTURE_MANAGER

View File

@ -1,9 +1,9 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
#pragma once
#ifndef RENDER_BGFX_UTIL
#define RENDER_BGFX_UTIL
#ifndef __RENDER_BGFX_UTIL__
#define __RENDER_BGFX_UTIL__
#pragma once
#include <bgfx/bgfx.h>
@ -15,4 +15,4 @@ public:
static uint64_t get_blend_state(uint32_t blend);
};
#endif // __RENDER_BGFX_UTIL__
#endif // RENDER_BGFX_UTIL

View File

@ -559,10 +559,9 @@ void renderer_bgfx::render_textured_quad(render_primitive* prim, bgfx::Transient
uint16_t tex_width(prim->texture.width);
uint16_t tex_height(prim->texture.height);
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(prim->flags & PRIMFLAG_TEXFORMAT_MASK,
tex_width, tex_height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base);
bgfx::TextureHandle texture = bgfx::createTexture2D(tex_width, tex_height, false, 1, bgfx::TextureFormat::RGBA8, texture_flags, mem);
bgfx::TextureHandle texture = m_textures->create_or_update_mame_texture(prim->flags & PRIMFLAG_TEXFORMAT_MASK
, tex_width, tex_height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base, prim->texture.seqid
, texture_flags, prim->texture.unique_id, prim->texture.old_id);
bgfx_effect** effects = PRIMFLAG_GET_SCREENTEX(prim->flags) ? m_screen_effect : m_gui_effect;
@ -570,8 +569,6 @@ void renderer_bgfx::render_textured_quad(render_primitive* prim, bgfx::Transient
bgfx::setVertexBuffer(0,buffer);
bgfx::setTexture(0, effects[blend]->uniform("s_tex")->handle(), texture);
effects[blend]->submit(m_ortho_view->get_index());
bgfx::destroy(texture);
}
#define MAX_TEMP_COORDS 100

View File

@ -2,8 +2,8 @@
// copyright-holders:Ryan Holtz
#pragma once
#ifndef __RENDER_BGFX__
#define __RENDER_BGFX__
#ifndef RENDER_BGFX
#define RENDER_BGFX
#include <bgfx/bgfx.h>
@ -162,4 +162,4 @@ private:
static uint32_t s_current_view;
};
#endif
#endif // RENDER_BGFX

View File

@ -453,7 +453,8 @@ void d3d_texture_manager::create_resources()
texture.height = m_default_bitmap.height();
texture.palette = nullptr;
texture.seqid = 0;
texture.osddata = 0;
texture.unique_id = ~0ULL;
texture.old_id = ~0ULL;
// now create it
auto tex = std::make_unique<texture_info>(this, &texture, win->prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
@ -484,10 +485,10 @@ texture_info *d3d_texture_manager::find_texinfo(const render_texinfo *texinfo, u
// find a match
for (auto it = m_texture_list.begin(); it != m_texture_list.end(); it++)
{
uint32_t test_screen = (uint32_t)(*it)->get_texinfo().osddata >> 1;
uint32_t test_page = (uint32_t)(*it)->get_texinfo().osddata & 1;
uint32_t prim_screen = (uint32_t)texinfo->osddata >> 1;
uint32_t prim_page = (uint32_t)texinfo->osddata & 1;
uint32_t test_screen = (uint32_t)((*it)->get_texinfo().unique_id >> 57);
uint32_t test_page = (uint32_t)((*it)->get_texinfo().unique_id >> 56) & 1;
uint32_t prim_screen = (uint32_t)(texinfo->unique_id >> 57);
uint32_t prim_page = (uint32_t)(texinfo->unique_id >> 56) & 1;
if (test_screen != prim_screen || test_page != prim_page)
continue;