-bgfx: Do texture format conversion via a full-screen GPU pass. [Ryan Holtz]

This commit is contained in:
MooglyGuy 2019-10-13 20:55:11 +02:00
parent cd6b9ac9be
commit 61b2a8afaf
40 changed files with 491 additions and 67 deletions

View File

@ -0,0 +1,123 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
//============================================================
//
// blit_palette16.json: A palettized texture-to-target copy.
//
//============================================================
{
// blend (required): The blend state for this effect.
"blend": {
// equation (optional): What equation to perform on the source and destination blend values.
// values: "add", "sub", "revSub", "min", "max"
// default: "add"
//
// "subtract" and "revSubtract" are provided as aliases for "sub" and "revSub"
"equation": "add",
// blend function parameters (optional): What factors to use in the blend function when calculating the final pixel.
// values: "0", "1", "srccolor", "1-srccolor", "dstcolor", "1-dstcolor", "srcalpha", "1-srcalpha", "dstalpha", "1-dstalpha"
// defaults (srcColor, srcAlpha): "1"
// defaults (dstColor, dstAlpha): "0"
//
// "zero", "one", "invsrccolor", "invdstcolor", "invsrcalpha", and "invdstalpha" are provided as aliases for "0", "1", "1-srccolor", "1-dstcolor", "1-srcalpha", and "1-dstalpha"
"srcColor": "srcalpha",
"dstColor": "1-srcalpha",
"srcAlpha": "srcalpha",
"dstAlpha": "1-srcalpha"
},
// depth (required): The depth state for this effect.
"depth": {
// function (optional): The depth function to use when drawing.
// values: "never", "less", "equal", "lequal", "greater", "notequal", "gequal", "always"
// default: "always"
"function": "always",
// writeenable (optional): Whether to store Z-buffer data.
// values: true, false
// default: false
"writeenable": false
},
// cull (required): The cull mode for this effect.
"cull": {
// mode (optional): What winding, if any, to cull.
// values: "none", "cw", "ccw"
// default: "ccw"
//
// "clockwise" and "counterclockwise" are provided as aliases for "cw" and "ccw"
"mode": "none"
},
// write (required): Write enable for color and alpha channels.
"write": {
// rgb (optional): Whether to store color data when drawing.
// values: true, false
// default: false
"rgb": true,
// alpha (optional): Whether to store alpha data when drawing.
// values: true, false
// default: false
"alpha": true
},
// vertex (required): The vertex shader to use when drawing.
// value: A string containing the path and name of a shader file to use, minus the extension.
"vertex": "chains/misc/vs_blit",
// pixel/fragment (required): The pixel or fragment shader to use when drawing.
// value: A string containing the path and name of a shader file to use, minus the extension.
"fragment": "chains/misc/fs_blit_palette16",
// uniforms (required): The list of uniforms for this effect. Can be empty, but must exist.
"uniforms": [
{
// name (required): The name of the uniform, as used in either the vertex or pixel/fragment shader.
// value: A string containing the name of the uniform as described above.
//
// NOTE: Some names correspond to special values that will be automatically filled by the BGFX
// code if they are used by the shader. These names are:
// "u_screen_dims"
// The dimensions of the first texture input if present, otherwise the dimensions of the output window.
// Valid values: xy
// "u_inv_screen_dims"
// The reciprocal of u_screen_dims.
// Valid values: xy
// "u_source_dims"
// The size, in pixels, of the screen texture incoming to the chain.
// Valid values: xy
// "u_rotation_type"
// This screen's rotation type. 0 if ROT0, 1 if ROT90, 2 if ROT180, 3 of ROT270.
// Valid values: x
// "u_swap_xy"
// Whether this screen is swapped on the X and Y axes. 1 if true, 0 if false.
// Valid values: x
// "u_quad_dims"
// The dimensions, in pixels, occupied by this one screen primitive itself in the output window.
// Valid values: xy
// "u_tex_sizeN"
// The dimensions, in pixels, of the texture in input pair N. Starts at 0.
// valid values: xy
"name": "s_tex",
// type (required): The type of the uniform.
// values: "int", "vec4", "mat3", "mat4"
//
// Note: "int" should only be used for samplers.
"type": "int",
// values (required): The array of numbers with which to initialize the uniform.
// value: A JSON array containin the correct amount of numbers to initialize a uniform of the
// above-specified type. The following size rules should be followed:
// "int": 1 float
// "vec4": 4 floats
// "mat3": 9 floats
// "mat4": 16 floats
"values": [ 1.0 ]
},
{ "name": "s_pal", "type": "int", "values": [ 1.0 ] },
{ "name": "u_inv_tex_size1", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }
]
}

View File

@ -0,0 +1,26 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
//===============================================================
//
// texconv_palette16.json: A palettized texture-to-target copy.
//
//===============================================================
{
"blend": {
"equation": "add",
"srcColor": "srcalpha",
"dstColor": "1-srcalpha",
"srcAlpha": "srcalpha",
"dstAlpha": "1-srcalpha"
},
"depth": { "function": "always", "writeenable": false },
"cull": { "mode": "none" },
"write": { "rgb": true, "alpha": true },
"vertex": "chains/misc/vs_blit",
"fragment": "chains/misc/fs_blit_palette16",
"uniforms": [
{ "name": "s_tex", "type": "int", "values": [ 1.0 ] },
{ "name": "s_pal", "type": "int", "values": [ 1.0 ] },
{ "name": "u_inv_tex_size1", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }
]
}

View File

@ -0,0 +1,25 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
//===============================================================
//
// texconv_rgb32.json: An opaque texture-to-target copy.
//
//===============================================================
{
"blend": {
"equation": "add",
"srcColor": "srcalpha",
"dstColor": "1-srcalpha",
"srcAlpha": "srcalpha",
"dstAlpha": "1-srcalpha"
},
"depth": { "function": "always", "writeenable": false },
"cull": { "mode": "none" },
"write": { "rgb": true, "alpha": true },
"vertex": "chains/misc/vs_blit",
"fragment": "chains/misc/fs_blit_rgb32",
"uniforms": [
{ "name": "s_tex", "type": "int", "values": [ 1.0 ] },
{ "name": "s_pal", "type": "int", "values": [ 1.0 ] }
]
}

View File

@ -0,0 +1,27 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
//===============================================================
//
// texconv_yuy16.json: An opaque texture-to-target copy with
// YUY16 conversion.
//
//===============================================================
{
"blend": {
"equation": "add",
"srcColor": "srcalpha",
"dstColor": "1-srcalpha",
"srcAlpha": "srcalpha",
"dstAlpha": "1-srcalpha"
},
"depth": { "function": "always", "writeenable": false },
"cull": { "mode": "none" },
"write": { "rgb": true, "alpha": true },
"vertex": "chains/misc/vs_blit",
"fragment": "chains/misc/fs_blit_yuy16",
"uniforms": [
{ "name": "s_tex", "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 ] }
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -496,7 +496,7 @@ void render_texture::get_scaled(u32 dwidth, u32 dheight, render_texinfo &texinfo
// palette for a texture
//-------------------------------------------------
const rgb_t *render_texture::get_adjusted_palette(render_container &container)
const rgb_t *render_texture::get_adjusted_palette(render_container &container, u32 &out_length)
{
// override the palette with our adjusted palette
switch (m_format)
@ -506,7 +506,7 @@ const rgb_t *render_texture::get_adjusted_palette(render_container &container)
assert(m_bitmap->palette() != nullptr);
// return our adjusted palette
return container.bcg_lookup_table(m_format, m_bitmap->palette());
return container.bcg_lookup_table(m_format, out_length, m_bitmap->palette());
case TEXFORMAT_RGB32:
case TEXFORMAT_ARGB32:
@ -515,7 +515,7 @@ const rgb_t *render_texture::get_adjusted_palette(render_container &container)
// if no adjustment necessary, return nullptr
if (!container.has_brightness_contrast_gamma_changes())
return nullptr;
return container.bcg_lookup_table(m_format);
return container.bcg_lookup_table(m_format, out_length);
default:
assert(false);
@ -679,7 +679,7 @@ float render_container::apply_brightness_contrast_gamma_fp(float value)
// given texture mode
//-------------------------------------------------
const rgb_t *render_container::bcg_lookup_table(int texformat, palette_t *palette)
const rgb_t *render_container::bcg_lookup_table(int texformat, u32 &out_length, palette_t *palette)
{
switch (texformat)
{
@ -691,14 +691,17 @@ const rgb_t *render_container::bcg_lookup_table(int texformat, palette_t *palett
recompute_lookups();
}
assert (palette == &m_palclient->palette());
out_length = palette->max_index();
return &m_bcglookup[0];
case TEXFORMAT_RGB32:
case TEXFORMAT_ARGB32:
case TEXFORMAT_YUY16:
out_length = 256;
return m_bcglookup256;
default:
out_length = 0;
return nullptr;
}
}
@ -2267,7 +2270,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const
curitem.texture()->get_scaled(width, height, prim->texture, list, curitem.flags());
// set the palette
prim->texture.palette = curitem.texture()->get_adjusted_palette(container);
prim->texture.palette = curitem.texture()->get_adjusted_palette(container, prim->texture.palette_length);
// determine UV coordinates
prim->texcoords = oriented_texcoords[finalorient];

View File

@ -218,6 +218,7 @@ struct render_texinfo
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
u32 palette_length;
};
@ -436,7 +437,7 @@ public:
private:
// internal helpers
void get_scaled(u32 dwidth, u32 dheight, render_texinfo &texinfo, render_primitive_list &primlist, u32 flags = 0);
const rgb_t *get_adjusted_palette(render_container &container);
const rgb_t *get_adjusted_palette(render_container &container, u32 &out_length);
static const int MAX_TEXTURE_SCALES = 16;
@ -527,7 +528,7 @@ public:
bool has_brightness_contrast_gamma_changes() const { return (m_user.m_brightness != 1.0f || m_user.m_contrast != 1.0f || m_user.m_gamma != 1.0f); }
u8 apply_brightness_contrast_gamma(u8 value);
float apply_brightness_contrast_gamma_fp(float value);
const rgb_t *bcg_lookup_table(int texformat, palette_t *palette = nullptr);
const rgb_t *bcg_lookup_table(int texformat, u32 &out_length, palette_t *palette = nullptr);
private:
// an item describes a high level primitive that is added to a container

View File

@ -13,11 +13,14 @@
#include "slider.h"
#include "parameter.h"
#include "entryuniform.h"
#include "valueuniform.h"
#include "texturemanager.h"
#include "targetmanager.h"
#include "chainmanager.h"
#include "target.h"
#include "vertex.h"
#include "screen.h"
#include "clear.h"
#include "modules/osdwindow.h"
#include "chain.h"
@ -33,6 +36,7 @@ bgfx_chain::bgfx_chain(std::string name, std::string author, bool transform, tar
, m_target_list(target_list)
, m_current_time(0)
, m_screen_index(screen_index)
, m_has_converter(false)
{
for (bgfx_target* target : m_target_list)
{
@ -138,3 +142,31 @@ uint32_t bgfx_chain::applicable_passes()
return applicable_passes;
}
void bgfx_chain::prepend_converter(bgfx_effect *effect, chain_manager &chains)
{
clear_state *clear = new clear_state(BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL, 0, 1.0f, 0);
std::vector<bgfx_suppressor*> suppressors;
std::vector<bgfx_input_pair*> inputs;
std::vector<std::string> available_textures;
inputs.push_back(new bgfx_input_pair(0, "s_tex", "source", available_textures, "", chains, m_screen_index));
inputs.push_back(new bgfx_input_pair(1, "s_pal", "palette", available_textures, "", chains, m_screen_index));
std::vector<bgfx_entry_uniform*> uniforms;
float value = 1.0f;
float values[4] = { 1.0f, 1.0f, 0.0f, 0.0f };
uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("s_tex", bgfx::UniformType::Sampler), &value, 1));
uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("s_pal", bgfx::UniformType::Sampler), &value, 1));
uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("u_tex_size0", bgfx::UniformType::Vec4), values, 4));
uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("u_tex_size1", bgfx::UniformType::Vec4), values, 4));
uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("u_inv_tex_size0", bgfx::UniformType::Vec4), values, 4));
uniforms.push_back(new bgfx_value_uniform(new bgfx_uniform("u_inv_tex_size1", bgfx::UniformType::Vec4), values, 4));
m_entries.insert(m_entries.begin(), new bgfx_chain_entry("XXconvert", effect, clear, suppressors, inputs, uniforms, m_targets, "screen"));
m_has_converter = true;
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.create_target("screen", bgfx::TextureFormat::RGBA8, screen_width, screen_height, TARGET_STYLE_GUEST, true, false, 1, m_screen_index);
}

View File

@ -38,7 +38,10 @@ public:
std::vector<bgfx_slider*>& sliders() { return m_sliders; }
std::vector<bgfx_chain_entry*>& entries() { return m_entries; }
uint32_t applicable_passes();
bool transform() { return m_transform; }
bool transform() const { return m_transform; }
bool has_converter() const { return m_has_converter; }
void prepend_converter(bgfx_effect *effect, chain_manager &chains);
private:
std::string m_name;
@ -53,6 +56,7 @@ private:
std::map<std::string, bgfx_target*> m_target_map;
int64_t m_current_time;
uint32_t m_screen_index;
bool m_has_converter;
};
#endif // __DRAWBGFX_CHAIN__

View File

@ -11,8 +11,8 @@
#pragma once
#ifndef __DRAWBGFX_CHAIN_ENTRY__
#define __DRAWBGFX_CHAIN_ENTRY__
#ifndef DRAWBGFX_CHAIN_ENTRY
#define DRAWBGFX_CHAIN_ENTRY
#include <bgfx/bgfx.h>

View File

@ -84,7 +84,7 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
texture_name = chains.options().value(option.c_str());
}
if (texture_name != "" && texture_name != "screen")
if (texture_name != "" && texture_name != "screen" && texture_name != "palette")
{
if (selection == "")
{

View File

@ -49,6 +49,7 @@ chain_manager::chain_manager(running_machine& machine, osd_options& options, tex
{
refresh_available_chains();
parse_chain_selections(options.bgfx_screen_chains());
init_texture_converters();
}
chain_manager::~chain_manager()
@ -56,6 +57,15 @@ chain_manager::~chain_manager()
destroy_chains();
}
void chain_manager::init_texture_converters()
{
m_converters.push_back(nullptr);
m_converters.push_back(m_effects.effect("misc/texconv_palette16"));
m_converters.push_back(m_effects.effect("misc/texconv_rgb32"));
m_converters.push_back(nullptr);
m_converters.push_back(m_effects.effect("misc/texconv_yuy16"));
}
void chain_manager::refresh_available_chains()
{
m_available_chains.clear();
@ -288,18 +298,74 @@ bgfx_chain* chain_manager::screen_chain(uint32_t screen)
}
}
void chain_manager::process_screen_quad(uint32_t view, uint32_t screen, render_primitive* prim, osd_window &window)
void chain_manager::process_screen_quad(uint32_t view, uint32_t screen, render_primitive* prim, osd_window& window)
{
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_texture* texture = screen < m_screen_textures.size() ? m_screen_textures[screen] : nullptr;
bgfx_texture* palette = screen < m_screen_palettes.size() ? m_screen_palettes[screen] : nullptr;
std::string full_name = "screen" + std::to_string(screen);
bgfx_texture *texture = new bgfx_texture(full_name, bgfx::TextureFormat::RGBA8, 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);
const uint32_t src_format = (prim->flags & PRIMFLAG_TEXFORMAT_MASK) >> PRIMFLAG_TEXFORMAT_SHIFT;
const bool needs_conversion = m_converters[src_format] != nullptr;
std::string screen_index = std::to_string(screen);
std::string source_name = "source" + screen_index;
std::string screen_name = "screen" + screen_index;
std::string palette_name = "palette" + screen_index;
std::string full_name = needs_conversion ? source_name : screen_name;
if (texture && (texture->width() != tex_width || texture->height() != tex_height))
{
m_textures.add_provider(full_name, nullptr);
delete texture;
texture = nullptr;
if (palette)
{
m_textures.add_provider(palette_name, nullptr);
delete palette;
palette = nullptr;
}
}
bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::RGBA8;
uint16_t pitch = tex_width;
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, prim->flags & PRIMFLAG_TEXFORMAT_MASK,
tex_width, tex_height, prim->texture.rowpixels, prim->texture.palette, prim->texture.base, &pitch);
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);
m_textures.add_provider(full_name, texture);
if (prim->texture.palette)
{
uint16_t palette_width = (uint16_t)std::min(prim->texture.palette_length, 256U);
uint16_t palette_height = (uint16_t)std::max(prim->texture.palette_length / 256, 1U);
const bgfx::Memory *palmem = bgfx::copy(prim->texture.palette, palette_width * palette_height * 4);
palette = new bgfx_texture(palette_name, bgfx::TextureFormat::BGRA8, palette_width, palette_height, palmem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT, palette_width);
m_textures.add_provider(palette_name, palette);
}
if (screen >= m_screen_textures.size())
{
m_screen_textures.push_back(texture);
if (palette)
{
m_screen_palettes.push_back(palette);
}
}
}
else
{
texture->update(mem, pitch);
if (prim->texture.palette)
{
const bgfx::Memory *palmem = bgfx::copy(prim->texture.palette, palette->width() * palette->height() * 4);
palette->update(palmem);
}
}
const bool any_targets_rebuilt = m_targets.update_target_sizes(screen, tex_width, tex_height, TARGET_STYLE_GUEST);
if (any_targets_rebuilt)
{
@ -313,11 +379,12 @@ void chain_manager::process_screen_quad(uint32_t view, uint32_t screen, render_p
}
bgfx_chain* chain = screen_chain(screen);
if (needs_conversion && !chain->has_converter())
{
chain->prepend_converter(m_converters[src_format], *this);
}
chain->process(prim, view, screen, m_textures, window, bgfx_util::get_blend_state(PRIMFLAG_GET_BLENDMODE(prim->flags)));
view += chain->applicable_passes();
m_textures.add_provider(full_name, nullptr);
delete texture;
}
std::vector<render_primitive*> chain_manager::count_screens(render_primitive* prim)

View File

@ -77,6 +77,8 @@ private:
void destroy_chains();
void reload_chains();
void init_texture_converters();
void refresh_available_chains();
void destroy_unloaded_chains();
void find_available_chains(std::string root, std::string path);
@ -106,6 +108,9 @@ private:
std::vector<ui::menu_item> m_selection_sliders;
std::vector<std::unique_ptr<slider_state>> m_core_sliders;
std::vector<int32_t> m_current_chain;
std::vector<bgfx_texture*> m_screen_textures;
std::vector<bgfx_texture*> m_screen_palettes;
std::vector<bgfx_effect*> m_converters;
static const uint32_t CHAIN_NONE;
};

View File

@ -52,11 +52,5 @@ void bgfx_effect::submit(int view, uint64_t blend)
bgfx_uniform* bgfx_effect::uniform(std::string name)
{
std::map<std::string, bgfx_uniform*>::iterator iter = m_uniforms.find(name);
if (iter != m_uniforms.end())
{
return iter->second;
}
return nullptr;
return iter != m_uniforms.end() ? iter->second : nullptr;
}

View File

@ -11,8 +11,8 @@
#pragma once
#ifndef __DRAWBGFX_ENTRY_UNIFORM__
#define __DRAWBGFX_ENTRY_UNIFORM__
#ifndef DRAWBGFX_ENTRY_UNIFORM
#define DRAWBGFX_ENTRY_UNIFORM
#include <bgfx/bgfx.h>

View File

@ -50,13 +50,23 @@ void bgfx_input_pair::bind(bgfx_effect *effect, const int32_t screen) const
std::string name = m_texture + std::to_string(screen);
bgfx_texture_handle_provider* provider = chains().textures().provider(name);
if (!provider)
return;
bgfx_uniform *tex_size = effect->uniform("u_tex_size" + std::to_string(m_index));
if (tex_size != nullptr)
if (tex_size && provider)
{
float values[2] = { float(provider->width()), 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()) };
inv_tex_size->set(values, sizeof(float) * 2);
}
bgfx::setTexture(m_index, effect->uniform(m_sampler)->handle(), chains().textures().handle(name));
}

View File

@ -0,0 +1,19 @@
$input v_color0, v_texcoord0
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
#include "common.sh"
// Samplers
SAMPLER2D(s_tex, 0);
SAMPLER2D(s_pal, 1);
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;
gl_FragColor = vec4(texture2D(s_pal, palette_uv).rgb, 1.0) * v_color0;
}

View File

@ -0,0 +1,14 @@
$input v_color0, v_texcoord0
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
#include "common.sh"
// Samplers
SAMPLER2D(s_tex, 0);
void main()
{
gl_FragColor = vec4(texture2D(s_tex, v_texcoord0).rgb, 1.0) * v_color0;
}

View File

@ -0,0 +1,37 @@
$input v_color0, v_texcoord0
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
#include "common.sh"
// Samplers
SAMPLER2D(s_tex, 0);
vec4 u_tex_size0;
vec4 u_inv_tex_size0;
vec3 ycc_to_rgb(float y, float cb, float cr)
{
float r = saturate(y + 1.40200 * (cr - 0.5));
float g = saturate(y - 0.34414 * (cb - 0.5) - 0.71414 * (cr - 0.5));
float b = saturate(y + 1.77200 * (cb - 0.5));
return vec3(r, g, b);
}
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);
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;
if (mod_val < 1.0)
gl_FragColor = vec4(ycc_to_rgb(srcpix0.g, cb, cr), 1.0) * v_color0;
else
gl_FragColor = vec4(ycc_to_rgb(srcpix1.g, cb, cr), 1.0) * v_color0;
}

View File

@ -77,6 +77,7 @@ bgfx_suppressor* suppressor_reader::read_from_value(const Value& value, std::str
bool suppressor_reader::validate_parameters(const Value& value, std::string prefix)
{
if (!READER_CHECK(value["type"].IsString(), (prefix + "Value 'type' must be a string\n").c_str())) return false;
if (!READER_CHECK(value.HasMember("name"), (prefix + "Must have string value 'name'\n").c_str())) return false;
if (!READER_CHECK(value["name"].IsString(), (prefix + "Value 'name' must be a string\n").c_str())) return false;
if (!READER_CHECK(value.HasMember("value"), (prefix + "Must have numeric or array value 'value'\n").c_str())) return false;

View File

@ -32,7 +32,7 @@ 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)
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)
: m_name(name)
, m_format(format)
, m_width(width)
@ -40,10 +40,16 @@ bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, u
{
bgfx::TextureInfo info;
bgfx::calcTextureSize(info, width, height, 1, false, false, 1, format);
m_texture = bgfx::createTexture2D(width, height, false, 1, format, flags, data);
m_texture = bgfx::createTexture2D(width, height, false, 1, format, flags, nullptr);
bgfx::updateTexture2D(m_texture, 0, 0, 0, 0, width, height, data, pitch);
}
bgfx_texture::~bgfx_texture()
{
bgfx::destroy(m_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);
}

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);
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);
virtual ~bgfx_texture();
// Getters
@ -34,6 +34,8 @@ public:
virtual bgfx::TextureHandle texture() const override { return m_texture; }
virtual bool is_target() const override { return false; }
void update(const bgfx::Memory *data, uint16_t pitch = UINT16_MAX);
protected:
std::string m_name;
bgfx::TextureFormat::Enum m_format;

View File

@ -116,8 +116,10 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
}
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);
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, width, height, rowpixels, palette, base, &pitch);
bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)width, (uint16_t)height, mem, pitch);
return handle;
}
}
@ -142,8 +144,10 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
}
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);
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, width, height, rowpixels, palette, base, &pitch);
bgfx::updateTexture2D(handle, 0, 0, 0, 0, (uint16_t)width, (uint16_t)height, mem, pitch);
return handle;
}
}
@ -151,9 +155,11 @@ bgfx::TextureHandle texture_manager::create_or_update_mame_texture(uint32_t form
}
}
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);
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, width, height, rowpixels, palette, base, &pitch);
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);
m_mame_textures[key] = { handle, seqid, width, height };
return handle;

View File

@ -14,37 +14,57 @@
#include "render.h"
const bgfx::Memory* bgfx_util::mame_texture_data_to_bgfx_texture_data(uint32_t format, int width, int height, int rowpixels, const rgb_t *palette, void *base)
const bgfx::Memory* bgfx_util::mame_texture_data_to_bgfx_texture_data(bgfx::TextureFormat::Enum &dst_format, uint32_t src_format, int width, int height, int rowpixels, const rgb_t *palette, void *base, uint16_t *out_pitch)
{
const bgfx::Memory* mem = bgfx::alloc(width * height * 4);
uint32_t* data = reinterpret_cast<uint32_t*>(mem->data);
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;
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32):
case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32):
dst_format = bgfx::TextureFormat::BGRA8;
if (out_pitch)
*out_pitch = rowpixels * 4;
break;
}
bgfx::calcTextureSize(info, rowpixels, height, 1, false, false, 1, dst_format);
return bgfx::copy(base, info.storageSize);
/*const bgfx::Memory* mem = bgfx::alloc(width * height * 4);
uint32_t* dst = reinterpret_cast<uint32_t*>(mem->data);
uint16_t* src16 = reinterpret_cast<uint16_t*>(base);
uint32_t* src32 = reinterpret_cast<uint32_t*>(base);
for (int y = 0; y < height; y++)
{
uint32_t* dst_line = data + y * width;
uint16_t* src_line16 = src16 + y * rowpixels;
uint32_t* src_line32 = src32 + y * rowpixels;
switch (format)
{
case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16):
copy_util::copyline_palette16(dst_line, src_line16, width, palette);
copy_util::copyline_palette16(dst, src16, width, palette);
src16 += rowpixels;
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_YUY16):
copy_util::copyline_yuy16_to_argb(dst_line, src_line16, width, palette, 1);
copy_util::copyline_yuy16_to_argb(dst, src16, width, palette, 1);
src16 += rowpixels;
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32):
copy_util::copyline_argb32(dst_line, src_line32, width, palette);
copy_util::copyline_argb32(dst, src32, width, palette);
src32 += rowpixels;
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32):
copy_util::copyline_rgb32(dst_line, src_line32, width, palette);
copy_util::copyline_rgb32(dst, src32, width, palette);
src32 += rowpixels;
break;
default:
break;
}
dst += width;
}
return mem;
return mem;*/
}
uint64_t bgfx_util::get_blend_state(uint32_t blend)

View File

@ -11,7 +11,7 @@
class bgfx_util
{
public:
static const bgfx::Memory* mame_texture_data_to_bgfx_texture_data(uint32_t 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 width, int height, int rowpixels, const rgb_t *palette, void *base, uint16_t *out_pitch = nullptr);
static uint64_t get_blend_state(uint32_t blend);
};

View File

@ -1140,8 +1140,10 @@ void renderer_bgfx::process_atlas_packs(std::vector<std::vector<rectangle_packer
continue;
}
m_hash_to_entry[rect.hash()] = rect;
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(rect.format(), rect.width(), rect.height(), rect.rowpixels(), rect.palette(), rect.base());
bgfx::updateTexture2D(m_texture_cache->texture(), 0, 0, rect.x(), rect.y(), rect.width(), rect.height(), mem);
bgfx::TextureFormat::Enum dst_format = bgfx::TextureFormat::RGBA8;
uint16_t pitch = rect.width();
const bgfx::Memory* mem = bgfx_util::mame_texture_data_to_bgfx_texture_data(dst_format, rect.format(), rect.width(), rect.height(), rect.rowpixels(), rect.palette(), rect.base(), &pitch);
bgfx::updateTexture2D(m_texture_cache->texture(), 0, 0, rect.x(), rect.y(), rect.width(), rect.height(), mem, pitch);
}
}
}