BGFX fixes for various backends (#8469) [Ryan Holtz]

* Fixed palette and UYVY conversion in all backends. Fixes MT07760.
* Fixed a typo in targetmanager.cpp, thanks LN for the heads-up.
This commit is contained in:
MooglyGuy 2021-08-19 19:07:28 +02:00 committed by GitHub
parent 70264c9e45
commit 190f50e0a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 233 additions and 80 deletions

View File

@ -118,6 +118,8 @@
"values": [ 1.0 ]
},
{ "name": "s_pal", "type": "int", "values": [ 1.0 ] },
{ "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_inv_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_inv_tex_size1", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }
]
}

View File

@ -21,6 +21,8 @@
"uniforms": [
{ "name": "s_tex", "type": "int", "values": [ 1.0 ] },
{ "name": "s_pal", "type": "int", "values": [ 1.0 ] },
{ "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_inv_tex_size0", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_inv_tex_size1", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }
]
}

View File

@ -169,5 +169,5 @@ void bgfx_chain::insert_effect(uint32_t index, bgfx_effect *effect, std::string
const uint32_t screen_width = chains.targets().width(TARGET_STYLE_GUEST, m_screen_index);
const uint32_t screen_height = chains.targets().height(TARGET_STYLE_GUEST, m_screen_index);
m_targets.destroy_target("screen", m_screen_index);
m_targets.create_target("screen", bgfx::TextureFormat::RGBA8, screen_width, screen_height, TARGET_STYLE_GUEST, true, false, 1, m_screen_index);
m_targets.create_target("screen", bgfx::TextureFormat::BGRA8, screen_width, screen_height, TARGET_STYLE_GUEST, true, false, 1, m_screen_index);
}

View File

@ -47,6 +47,7 @@ chain_manager::chain_manager(running_machine& machine, osd_options& options, tex
, m_slider_notifier(slider_notifier)
, m_screen_count(0)
{
m_converters.clear();
refresh_available_chains();
parse_chain_selections(options.bgfx_screen_chains());
init_texture_converters();
@ -462,14 +463,15 @@ uint32_t chain_manager::update_screen_textures(uint32_t view, render_primitive *
}
}
bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::RGBA8;
bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::BGRA8;
uint16_t pitch = prim.m_rowpixels;
int convert_stride = 1;
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, prim.m_flags & PRIMFLAG_TEXFORMAT_MASK,
prim.m_rowpixels, tex_height, prim.m_prim->texture.palette, prim.m_prim->texture.base, &pitch);
prim.m_rowpixels, tex_height, prim.m_prim->texture.palette, prim.m_prim->texture.base, pitch, convert_stride);
if (texture == nullptr)
{
bgfx_texture *texture = new bgfx_texture(full_name, dst_format, tex_width, tex_height, mem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT, pitch, prim.m_rowpixels);
bgfx_texture *texture = new bgfx_texture(full_name, dst_format, tex_width, tex_height, mem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT, pitch, prim.m_rowpixels, convert_stride);
m_textures.add_provider(full_name, texture);
if (prim.m_prim->texture.palette)

View File

@ -42,6 +42,7 @@ bgfx_input_pair::bgfx_input_pair(int index, std::string sampler, std::string tex
bgfx_input_pair::~bgfx_input_pair()
{
m_slider_state.reset();
}
void bgfx_input_pair::bind(bgfx_effect *effect, const int32_t screen) const
@ -58,14 +59,14 @@ void bgfx_input_pair::bind(bgfx_effect *effect, const int32_t screen) const
bgfx_uniform *tex_size = effect->uniform("u_tex_size" + std::to_string(m_index));
if (tex_size && provider)
{
float values[2] = { float(provider->width()), float(provider->height()) };
float values[2] = { float(provider->rowpixels()), float(provider->height()) };
tex_size->set(values, sizeof(float) * 2);
}
bgfx_uniform *inv_tex_size = effect->uniform("u_inv_tex_size" + std::to_string(m_index));
if (inv_tex_size && provider)
{
float values[2] = { 1.0f / float(provider->width()), 1.0f / float(provider->height()) };
float values[2] = { 1.0f / float(provider->rowpixels()), 1.0f / float(provider->height()) };
inv_tex_size->set(values, sizeof(float) * 2);
}

View File

@ -9,11 +9,28 @@ $input v_color0, v_texcoord0
SAMPLER2D(s_tex, 0);
SAMPLER2D(s_pal, 1);
uniform vec4 u_tex_size0;
uniform vec4 u_inv_tex_size0;
uniform vec4 u_inv_tex_size1;
void main()
{
vec2 palette_uv = texture2D(s_tex, v_texcoord0).rg;
palette_uv.xy = (palette_uv.xy * vec2(256.0, 256.0)) * u_inv_tex_size1.xy;
// Logic taken from fs_blit_yuy16.sc - we need to do this, because
// the D3D9 BGFX backend claims to support RG8, but does so in
// a faulty way by using A8L8, which is not an appropriate format
// for representing an RG8 texture.
vec2 half_texel = u_inv_tex_size0.xy * vec2(0.5, 0.5);
vec2 original_uv = v_texcoord0.xy * u_tex_size0.xy;
float mod_val = mod(original_uv.x, 2.0);
vec2 rounded_uv = vec2(original_uv.x - mod_val, original_uv.y);
vec4 srcpix = texture2D(s_tex, rounded_uv * u_inv_tex_size0.xy + half_texel.x);
vec2 palette_uv = (srcpix.ra * vec2(256.0, 256.0)) * u_inv_tex_size1.xy;
if (mod_val < 1.0)
palette_uv = (srcpix.bg * vec2(256.0, 256.0)) * u_inv_tex_size1.xy;
gl_FragColor = vec4(texture2D(s_pal, palette_uv).rgb, 1.0) * v_color0;
//gl_FragColor = texture2D(s_tex, v_texcoord0) * v_color0;
}

View File

@ -8,8 +8,6 @@ $input v_color0, v_texcoord0
// Samplers
SAMPLER2D(s_tex, 0);
#define round(X) floor((X)+0.5)
uniform vec4 u_tex_size0;
uniform vec4 u_inv_tex_size0;
@ -23,17 +21,17 @@ vec3 ycc_to_rgb(float y, float cb, float cr)
void main()
{
vec2 size_minus_one = u_tex_size0.xy - vec2(1.0, 1.0);
vec2 original_uv = round(v_texcoord0.xy * size_minus_one);
vec2 half_texel = u_inv_tex_size0.xy * vec2(0.5, 0.5);
vec2 original_uv = v_texcoord0.xy * u_tex_size0.xy;
float mod_val = mod(original_uv.x, 2.0);
vec2 rounded_uv = round(vec2(original_uv.x - mod_val, original_uv.y));
vec2 next_uv = rounded_uv + vec2(1.0, 0.0);
vec2 srcpix0 = texture2D(s_tex, rounded_uv / size_minus_one).rg;
vec2 srcpix1 = texture2D(s_tex, next_uv / size_minus_one).rg;
float cr = srcpix1.r;
float cb = srcpix0.r;
vec2 rounded_uv = vec2(original_uv.x - mod_val, original_uv.y);
vec4 srcpix = texture2D(s_tex, rounded_uv * u_inv_tex_size0.xy + half_texel.x);
float cr = srcpix.r;
float cb = srcpix.b;
if (mod_val < 1.0)
gl_FragColor = vec4(ycc_to_rgb(srcpix0.g, cb, cr), 1.0) * v_color0;
gl_FragColor = vec4(ycc_to_rgb(srcpix.g, cb, cr), 1.0) * v_color0;
else
gl_FragColor = vec4(ycc_to_rgb(srcpix1.g, cb, cr), 1.0) * v_color0;
gl_FragColor = vec4(ycc_to_rgb(srcpix.a, cb, cr), 1.0) * v_color0;
}

View File

@ -30,16 +30,24 @@ bgfx_target::bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uin
{
m_width *= m_scale;
m_height *= m_scale;
uint32_t wrap_mode = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
uint32_t filter_mode = filter ? (BGFX_SAMPLER_MIN_ANISOTROPIC | BGFX_SAMPLER_MAG_ANISOTROPIC) : (BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT);
uint32_t depth_flags = wrap_mode | (BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT);
m_textures = new bgfx::TextureHandle[m_page_count];
m_textures = new bgfx::TextureHandle[m_page_count * 2];
m_targets = new bgfx::FrameBufferHandle[m_page_count];
for (int page = 0; page < m_page_count; page++)
{
m_textures[page] = bgfx::createTexture2D(m_width, m_height, false, 1, format, wrap_mode | filter_mode | BGFX_TEXTURE_RT);
assert(m_textures[page].idx != 0xffff);
m_targets[page] = bgfx::createFrameBuffer(1, &m_textures[page], false);
m_textures[m_page_count + page] = bgfx::createTexture2D(m_width, m_height, false, 1, bgfx::TextureFormat::D24, depth_flags | BGFX_TEXTURE_RT);
assert(m_textures[m_page_count + page].idx != 0xffff);
bgfx::TextureHandle handles[2] = { m_textures[page], m_textures[m_page_count + page] };
m_targets[page] = bgfx::createFrameBuffer(2, handles, false);
assert(m_targets[page].idx != 0xffff);
}
@ -64,7 +72,7 @@ bgfx_target::bgfx_target(void *handle, uint16_t width, uint16_t height)
, m_page_count(0)
{
m_targets = new bgfx::FrameBufferHandle[1];
m_targets[0] = bgfx::createFrameBuffer(handle, width, height);
m_targets[0] = bgfx::createFrameBuffer(handle, width, height, bgfx::TextureFormat::Count, bgfx::TextureFormat::D24);
// No backing texture
}
@ -81,6 +89,7 @@ bgfx_target::~bgfx_target()
for (int page = 0; page < m_page_count; page++)
{
bgfx::destroy(m_targets[page]);
bgfx::destroy(m_textures[m_page_count + page]);
bgfx::destroy(m_textures[page]);
}
delete [] m_textures;

View File

@ -44,11 +44,12 @@ public:
uint32_t screen_index() const { return m_screen; }
// bgfx_texture_handle_provider
virtual bgfx::TextureHandle texture() const override;
virtual bool is_target() const override { return true; }
virtual uint16_t width() const override { return m_width; }
virtual uint16_t height() const override { return m_height; }
virtual uint16_t rowpixels() const override { return m_width; }
virtual bgfx::TextureHandle texture() const override;
virtual bool is_target() const override { return true; }
virtual int convert_stride() const override { return 1; }
private:
std::string m_name;

View File

@ -47,11 +47,14 @@ target_manager::~target_manager()
bgfx_target* target_manager::create_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t style, bool double_buffer, bool filter, uint16_t scale, uint32_t screen)
{
auto* target = new bgfx_target(name, format, width, height, style, double_buffer, filter, scale, screen);
std::string full_name = name + std::to_string(screen);
m_targets[full_name] = target;
auto iter = m_targets.find(full_name);
if (iter != m_targets.end())
destroy_target(name, screen);
bgfx_target *target = new bgfx_target(name, format, width, height, style, double_buffer, filter, scale, screen);
m_targets[full_name] = target;
m_textures.add_provider(full_name, target);
return target;
@ -60,10 +63,10 @@ bgfx_target* target_manager::create_target(std::string name, bgfx::TextureFormat
void target_manager::destroy_target(std::string name, uint32_t screen)
{
std::string full_name = (screen < 0) ? name : (name + std::to_string(screen));
if (m_targets[full_name] != nullptr)
if (m_targets.find(full_name) != m_targets.end())
{
delete m_targets[full_name];
m_targets[full_name] = nullptr;
m_targets.erase(full_name);
m_textures.remove_provider(full_name);
}
}
@ -78,12 +81,11 @@ bgfx_target* target_manager::create_backbuffer(void *handle, uint16_t width, uin
bgfx_target* target_manager::target(uint32_t screen, std::string name)
{
std::string full_name = name + std::to_string(screen);
bgfx_target* target = m_targets[full_name];
if (target == nullptr)
if (m_targets.find(full_name) != m_targets.end())
{
osd_printf_verbose("Warning: Attempting to retrieve a nonexistent target '%s' for screen %d\n", name, screen);
}
return target;
return m_targets[full_name];
}
bool target_manager::update_target_sizes(uint32_t screen, uint16_t width, uint16_t height, uint32_t style)
@ -133,8 +135,8 @@ void target_manager::rebuild_targets(uint32_t screen, uint32_t style)
const uint16_t scale = target->scale();
const uint16_t width(sizes[screen].width());
const uint16_t height(sizes[screen].height());
delete target;
destroy_target(name, screen);
create_target(name, format, width, height, style, double_buffered, filter, scale, screen);
}
}
@ -165,7 +167,7 @@ void target_manager::create_target_if_nonexistent(uint32_t screen, std::string n
{
if (style == TARGET_STYLE_CUSTOM) return;
if (m_targets[name + std::to_string(screen)] != nullptr)
if (m_targets.find(name + std::to_string(screen)) != m_targets.end())
{
return;
}
@ -174,7 +176,7 @@ void target_manager::create_target_if_nonexistent(uint32_t screen, std::string n
uint16_t width(sizes[screen].width());
uint16_t height(sizes[screen].height());
create_target(name, bgfx::TextureFormat::RGBA8, width, height, style, double_buffered, filter, 1, screen);
create_target(name, bgfx::TextureFormat::BGRA8, width, height, style, double_buffered, filter, 1, screen);
}
uint16_t target_manager::width(uint32_t style, uint32_t screen)

View File

@ -60,7 +60,7 @@ bgfx_target* target_reader::read_from_value(const Value& value, std::string pref
break;
}
return chains.targets().create_target(target_name, bgfx::TextureFormat::RGBA8, width, height, mode, double_buffer, bilinear, scale, screen_index);
return chains.targets().create_target(target_name, bgfx::TextureFormat::BGRA8, width, height, mode, double_buffer, bilinear, scale, screen_index);
}
bool target_reader::validate_parameters(const Value& value, std::string prefix)

View File

@ -15,6 +15,8 @@ bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, u
, m_format(format)
, m_width(width)
, m_height(height)
, m_rowpixels(width)
, m_convert_stride(1)
{
bgfx::TextureInfo info;
bgfx::calcTextureSize(info, width, height, 1, false, false, 1, format);
@ -32,17 +34,18 @@ bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, u
}
}
bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, const bgfx::Memory* data, uint32_t flags, uint16_t pitch, uint16_t rowpixels)
bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, const bgfx::Memory* data, uint32_t flags, uint16_t pitch, uint16_t rowpixels, int convert_stride)
: m_name(name)
, m_format(format)
, m_width(width)
, m_height(height)
, m_rowpixels(rowpixels ? rowpixels : width)
, m_convert_stride(convert_stride)
{
bgfx::TextureInfo info;
bgfx::calcTextureSize(info, m_rowpixels, height, 1, false, false, 1, format);
m_texture = bgfx::createTexture2D(m_rowpixels, height, false, 1, format, flags, nullptr);
bgfx::updateTexture2D(m_texture, 0, 0, 0, 0, m_rowpixels, height, data, pitch);
bgfx::calcTextureSize(info, m_rowpixels / m_convert_stride, height, 1, false, false, 1, format);
m_texture = bgfx::createTexture2D(m_rowpixels / m_convert_stride, height, false, 1, format, flags, nullptr);
bgfx::updateTexture2D(m_texture, 0, 0, 0, 0, m_rowpixels / m_convert_stride, height, data, pitch);
}
bgfx_texture::~bgfx_texture()
@ -52,5 +55,5 @@ bgfx_texture::~bgfx_texture()
void bgfx_texture::update(const bgfx::Memory *data, uint16_t pitch)
{
bgfx::updateTexture2D(m_texture, 0, 0, 0, 0, m_width, m_height, data, pitch);
bgfx::updateTexture2D(m_texture, 0, 0, 0, 0, m_rowpixels / m_convert_stride, m_height, data, pitch);
}

View File

@ -21,7 +21,7 @@ class bgfx_texture : public bgfx_texture_handle_provider
{
public:
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_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP, uint16_t pitch = UINT16_MAX, uint16_t rowpixels = 0);
bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, const bgfx::Memory* data, uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP, uint16_t pitch = UINT16_MAX, uint16_t rowpixels = 0, int convert_stride = 1);
virtual ~bgfx_texture();
// Getters
@ -29,11 +29,12 @@ public:
bgfx::TextureFormat::Enum format() const { return m_format; }
// bgfx_texture_handle_provider
virtual bgfx::TextureHandle texture() const override { return m_texture; }
virtual bool is_target() const override { return false; }
virtual uint16_t width() const override { return m_width; }
virtual uint16_t height() const override { return m_height; }
virtual uint16_t rowpixels() const override { return m_rowpixels; }
virtual bgfx::TextureHandle texture() const override { return m_texture; }
virtual bool is_target() const override { return false; }
virtual int convert_stride() const override { return m_convert_stride; }
void update(const bgfx::Memory *data, uint16_t pitch = UINT16_MAX);
@ -43,6 +44,7 @@ protected:
uint16_t m_width;
uint16_t m_height;
uint16_t m_rowpixels;
int m_convert_stride;
bgfx::TextureHandle m_texture;
};

View File

@ -25,6 +25,7 @@ public:
virtual uint16_t width() const = 0;
virtual uint16_t height() const = 0;
virtual uint16_t rowpixels() const = 0;
virtual int convert_stride() const = 0;
};
#endif // __DRAWBGFX_TEXTURE_HANDLE_PROVIDER__

View File

@ -87,7 +87,7 @@ bgfx_texture* texture_manager::create_png_texture(std::string path, std::string
{
texture_name += std::to_string(screen);
}
bgfx_texture* texture = create_texture(texture_name, bgfx::TextureFormat::RGBA8, width, height, data, flags);
bgfx_texture* texture = create_texture(texture_name, bgfx::TextureFormat::BGRA8, width, height, data, flags);
delete [] data;
@ -122,8 +122,9 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
{
bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::BGRA8;
uint16_t pitch = width;
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, format, rowpixels, height, palette, base, &pitch);
bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)width, (uint16_t)height, mem, pitch);
int convert_stride = 1;
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, format, rowpixels, height, palette, base, pitch, convert_stride);
bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)(rowpixels / convert_stride), (uint16_t)height, mem, pitch);
return handle;
}
}
@ -150,8 +151,9 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
{
bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::BGRA8;
uint16_t pitch = width;
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, format, rowpixels, height, palette, base, &pitch);
bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)width, (uint16_t)height, mem, pitch);
int convert_stride = 1;
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, format, rowpixels, height, palette, base, pitch, convert_stride);
bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)(rowpixels / convert_stride), (uint16_t)height, mem, pitch);
return handle;
}
}
@ -161,9 +163,10 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::BGRA8;
uint16_t pitch = width;
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, format, rowpixels, height, palette, base, &pitch);
int convert_stride = 1;
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, format, rowpixels, height, palette, base, pitch, convert_stride);
handle = bgfx::createTexture2D(width, height, false, 1, dst_format, flags, nullptr);
bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)width, (uint16_t)height, mem, pitch);
bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)(rowpixels / convert_stride), (uint16_t)height, mem, pitch);
m_mame_textures[key] = { handle, seqid, width, height };
return handle;
@ -201,6 +204,6 @@ void texture_manager::remove_provider(std::string name, bool delete_provider)
{
delete m_textures[name];
}
m_textures[name] = nullptr;
m_textures.erase(name);
}
}

View File

@ -14,29 +14,29 @@
#include "render.h"
const bgfx::Memory* bgfx_util::mame_texture_data_to_bgfx_texture_data(bgfx::TextureFormat::Enum &dst_format, uint32_t src_format, int rowpixels, int height, const rgb_t *palette, void *base, uint16_t *out_pitch)
const bgfx::Memory* bgfx_util::mame_texture_data_to_bgfx_texture_data(bgfx::TextureFormat::Enum &dst_format, uint32_t src_format, int rowpixels, int height, const rgb_t *palette, void *base, uint16_t &out_pitch, int &convert_stride)
{
bgfx::TextureInfo info;
switch (src_format)
{
case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16):
case PRIMFLAG_TEXFORMAT(TEXFORMAT_YUY16):
dst_format = bgfx::TextureFormat::RG8;
if (out_pitch)
*out_pitch = rowpixels * 2;
dst_format = bgfx::TextureFormat::BGRA8;
convert_stride = 2;
out_pitch = rowpixels * 2;
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32):
case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32):
dst_format = bgfx::TextureFormat::BGRA8;
if (out_pitch)
*out_pitch = rowpixels * 4;
convert_stride = 1;
out_pitch = rowpixels * 4;
break;
}
bgfx::calcTextureSize(info, rowpixels, height, 1, false, false, 1, dst_format);
bgfx::calcTextureSize(info, rowpixels / convert_stride, height, 1, false, false, 1, dst_format);
return bgfx::copy(base, info.storageSize);
}
const bgfx::Memory* bgfx_util::mame_texture_data_to_argb32(uint32_t src_format, int width, int height, int rowpixels, const rgb_t *palette, void *base)
const bgfx::Memory* bgfx_util::mame_texture_data_to_bgra32(uint32_t src_format, int width, int height, int rowpixels, const rgb_t *palette, void *base)
{
const bgfx::Memory* mem = bgfx::alloc(rowpixels * height * 4);
auto* dst = reinterpret_cast<uint32_t*>(mem->data);
@ -48,19 +48,19 @@ const bgfx::Memory* bgfx_util::mame_texture_data_to_argb32(uint32_t src_format,
switch (src_format)
{
case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16):
copy_util::copyline_palette16(dst, src16, width, palette);
copy_util::copyline_palette16_to_bgra(dst, src16, width, palette);
src16 += rowpixels;
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_YUY16):
copy_util::copyline_yuy16_to_argb(dst, src16, width, palette, 1);
copy_util::copyline_yuy16_to_bgra(dst, src16, width, palette, 1);
src16 += rowpixels;
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32):
copy_util::copyline_argb32(dst, src32, width, palette);
copy_util::copyline_argb32_to_bgra(dst, src32, width, palette);
src32 += rowpixels;
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32):
copy_util::copyline_rgb32(dst, src32, width, palette);
copy_util::copyline_rgb32_to_bgra(dst, src32, width, palette);
src32 += rowpixels;
break;
default:

View File

@ -11,8 +11,8 @@
class bgfx_util
{
public:
static const bgfx::Memory* mame_texture_data_to_bgfx_texture_data(bgfx::TextureFormat::Enum &dst_format, uint32_t format, int width, int height, const rgb_t *palette, void *base, uint16_t *out_pitch = nullptr);
static const bgfx::Memory* mame_texture_data_to_argb32(uint32_t src_format, int width, int height, int rowpixels, const rgb_t *palette, void *base);
static const bgfx::Memory* mame_texture_data_to_bgfx_texture_data(bgfx::TextureFormat::Enum &dst_format, uint32_t format, int rowpixels, int height, const rgb_t *palette, void *base, uint16_t &out_pitch, int &convert_stride);
static const bgfx::Memory* mame_texture_data_to_bgra32(uint32_t src_format, int width, int height, int rowpixels, const rgb_t *palette, void *base);
static uint64_t get_blend_state(uint32_t blend);
};

View File

@ -24,6 +24,15 @@ public:
}
}
static inline void copyline_palette16_to_bgra(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette)
{
for (int x = 0; x < width; x++)
{
rgb_t srcpixel = palette[*src++];
*dst++ = 0xff000000 | (srcpixel.r() << 16) | (srcpixel.g() << 8) | srcpixel.b();
}
}
static inline void copyline_rgb32(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette)
{
int x;
@ -49,6 +58,32 @@ public:
}
}
static inline void copyline_rgb32_to_bgra(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette)
{
int x;
// palette (really RGB map) case
if (palette != nullptr)
{
for (x = 0; x < width; x++)
{
rgb_t srcpix = *src++;
uint32_t val = 0xff000000 | palette[0x200 + srcpix.b()] | palette[0x100 + srcpix.g()] | palette[srcpix.r()];
*dst++ = (val & 0xff00ff00) | ((val & 0x000000ff) << 16) | ((val & 0x00ff0000) >> 16);
}
}
// direct case
else
{
for (x = 0; x < width; x++)
{
rgb_t srcpix = *src++;
*dst++ = 0xff000000 | (srcpix.r() << 16) | (srcpix.g() << 8) | srcpix.b();
}
}
}
static inline void copyline_argb32(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette)
{
int x;
@ -73,6 +108,31 @@ public:
}
}
static inline void copyline_argb32_to_bgra(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette)
{
int x;
// palette (really RGB map) case
if (palette != nullptr)
{
for (x = 0; x < width; x++)
{
rgb_t srcpix = *src++;
uint32_t val = (srcpix & 0xff000000) | palette[0x200 + srcpix.b()] | palette[0x100 + srcpix.g()] | palette[srcpix.r()];
*dst++ = (val & 0xff00ff00) | ((val & 0x000000ff) << 16) | ((val & 0x00ff0000) >> 16);
}
}
// direct case
else
{
for (x = 0; x < width; x++)
{
rgb_t srcpix = *src++;
*dst++ = (srcpix.a() << 24) | (srcpix.r() << 16) | (srcpix.g() << 8) | srcpix.b();
}
}
}
static inline uint32_t ycc_to_rgb(uint8_t y, uint8_t cb, uint8_t cr)
{
/* original equations:
@ -116,14 +176,12 @@ public:
static inline void copyline_yuy16_to_argb(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette, int xprescale)
{
int x;
assert(width % 2 == 0);
// palette (really RGB map) case
if (palette != nullptr)
{
for (x = 0; x < width / 2; x++)
for (int x = 0; x < width / 2; x++)
{
uint16_t srcpix0 = *src++;
uint16_t srcpix1 = *src++;
@ -139,7 +197,7 @@ public:
// direct case
else
{
for (x = 0; x < width; x += 2)
for (int x = 0; x < width; x += 2)
{
uint16_t srcpix0 = *src++;
uint16_t srcpix1 = *src++;
@ -152,6 +210,55 @@ public:
}
}
}
static inline void copyline_yuy16_to_bgra(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette, int xprescale)
{
assert(width % 2 == 0);
// palette (really RGB map) case
if (palette != nullptr)
{
for (int x = 0; x < width / 2; x++)
{
uint16_t srcpix0 = *src++;
uint16_t srcpix1 = *src++;
uint8_t cb = srcpix0 & 0xff;
uint8_t cr = srcpix1 & 0xff;
for (int x2 = 0; x2 < xprescale; x2++)
{
uint32_t val = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
*dst++ = (val & 0xff00ff00) | ((val & 0x000000ff) << 16) | ((val & 0x00ff0000) >> 16);
}
for (int x2 = 0; x2 < xprescale; x2++)
{
uint32_t val = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
*dst++ = (val & 0xff00ff00) | ((val & 0x000000ff) << 16) | ((val & 0x00ff0000) >> 16);
}
}
}
// direct case
else
{
for (int x = 0; x < width; x += 2)
{
uint16_t srcpix0 = *src++;
uint16_t srcpix1 = *src++;
uint8_t cb = srcpix0 & 0xff;
uint8_t cr = srcpix1 & 0xff;
for (int x2 = 0; x2 < xprescale; x2++)
{
uint32_t val = ycc_to_rgb(srcpix0 >> 8, cb, cr);
*dst++ = (val & 0xff00ff00) | ((val & 0x000000ff) << 16) | ((val & 0x00ff0000) >> 16);
}
for (int x2 = 0; x2 < xprescale; x2++)
{
uint32_t val = ycc_to_rgb(srcpix1 >> 8, cb, cr);
*dst++ = (val & 0xff00ff00) | ((val & 0x000000ff) << 16) | ((val & 0x00ff0000) >> 16);
}
}
}
}
};
#endif // __RENDER_COPYUTIL__

View File

@ -108,8 +108,7 @@ renderer_bgfx::renderer_bgfx(std::shared_ptr<osd_window> w)
renderer_bgfx::~renderer_bgfx()
{
bgfx::reset(0, 0, BGFX_RESET_NONE);
//bgfx::touch(0);
//bgfx::frame();
if (m_avi_writer != nullptr && m_avi_writer->recording())
{
m_avi_writer->stop();
@ -125,6 +124,9 @@ renderer_bgfx::~renderer_bgfx()
}
// Cleanup.
if (m_ortho_view)
delete m_ortho_view;
delete m_chains;
delete m_effects;
delete m_shaders;
@ -349,7 +351,7 @@ int renderer_bgfx::create()
m_sliders_dirty = true;
uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT;
m_texture_cache = m_textures->create_texture("#cache", bgfx::TextureFormat::RGBA8, CACHE_SIZE, CACHE_SIZE, nullptr, flags);
m_texture_cache = m_textures->create_texture("#cache", bgfx::TextureFormat::BGRA8, CACHE_SIZE, CACHE_SIZE, nullptr, flags);
memset(m_white, 0xff, sizeof(uint32_t) * 16 * 16);
m_texinfo.push_back(rectangle_packer::packable_rectangle(WHITE_HASH, PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32), 16, 16, 16, nullptr, m_white));
@ -391,8 +393,8 @@ void renderer_bgfx::record()
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);
m_avi_target = m_targets->create_target("avibuffer", bgfx::TextureFormat::BGRA8, 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::BGRA8, BGFX_TEXTURE_BLIT_DST | BGFX_TEXTURE_READ_BACK);
if (m_avi_view == nullptr)
{
@ -599,9 +601,9 @@ void renderer_bgfx::render_textured_quad(render_primitive* prim, bgfx::Transient
bgfx::TextureHandle texture = BGFX_INVALID_HANDLE;
if (is_screen)
{
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_argb32(prim->flags & PRIMFLAG_TEXFORMAT_MASK
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgra32(prim->flags & PRIMFLAG_TEXFORMAT_MASK
, tex_width, tex_height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base);
texture = bgfx::createTexture2D(tex_width, tex_height, false, 1, bgfx::TextureFormat::RGBA8, texture_flags, mem);
texture = bgfx::createTexture2D(tex_width, tex_height, false, 1, bgfx::TextureFormat::BGRA8, texture_flags, mem);
}
else
{
@ -1164,10 +1166,11 @@ void renderer_bgfx::process_atlas_packs(std::vector<std::vector<rectangle_packer
continue;
}
m_hash_to_entry[rect.hash()] = rect;
bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::RGBA8;
bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::BGRA8;
uint16_t pitch = rect.width();
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, rect.format(), rect.rowpixels(), rect.height(), rect.palette(), rect.base(), &pitch);
bgfx::updateTexture2D(m_texture_cache->texture(), 0, 0, rect.x(), rect.y(), rect.width(), rect.height(), mem, pitch);
int convert_stride = 1;
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, rect.format(), rect.rowpixels(), rect.height(), rect.palette(), rect.base(), pitch, convert_stride);
bgfx::updateTexture2D(m_texture_cache->texture(), 0, 0, rect.x(), rect.y(), rect.width() / convert_stride, rect.height(), mem, pitch);
}
}
}