summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2023-02-02 18:30:29 +1100
committer Vas Crabb <vas@vastheman.com>2023-02-02 18:30:29 +1100
commitd35408d62802e445b66cc04e956bd9940581e37f (patch)
tree6344832f20e5345570b80246c887865e5817d4f0
parente2691b5e1399b5c377f90e018cd848b3b6d1ea79 (diff)
render/drawd3d.cpp: Fixed prescaling without HLSL - WRL COM pointer has some surprises.
Also added some additional error checking.
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.cpp10
-rw-r--r--src/osd/modules/render/drawd3d.cpp113
2 files changed, 61 insertions, 62 deletions
diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp
index 59a3762b4c2..aa75c4079b1 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.cpp
+++ b/src/osd/modules/render/d3d/d3dhlsl.cpp
@@ -1308,7 +1308,7 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
set_curr_effect(post_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("ShadowTexture", shadow_texture == nullptr ? nullptr : shadow_texture->get_finaltex());
+ curr_effect->set_texture("ShadowTexture", !shadow_texture ? nullptr : shadow_texture->get_finaltex());
curr_effect->set_int("ShadowTileMode", options->shadow_mask_tile_mode);
curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index].Get());
curr_effect->set_vector("BackColor", 3, back_color);
@@ -1461,7 +1461,7 @@ int shaders::vector_buffer_pass(d3d_render_target *rt, int source_index, poly_in
curr_effect->update_uniforms();
curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
- curr_effect->set_texture("LutTexture", lut_texture == nullptr ? nullptr : lut_texture->get_finaltex());
+ curr_effect->set_texture("LutTexture", !lut_texture ? nullptr : lut_texture->get_finaltex());
// we need to clear the vector render target here
next_index = rt->next_index(next_index);
@@ -1481,7 +1481,7 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
curr_effect->update_uniforms();
curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
- curr_effect->set_texture("LutTexture", lut_texture == nullptr ? nullptr : lut_texture->get_finaltex());
+ curr_effect->set_texture("LutTexture", !lut_texture ? nullptr : lut_texture->get_finaltex());
blit(backbuffer.Get(), false, poly->type(), vertnum, poly->count());
@@ -1513,7 +1513,7 @@ void shaders::ui_pass(poly_info *poly, int vertnum)
curr_effect->set_texture("Diffuse", diffuse_texture->get_finaltex());
curr_effect->update_uniforms();
- curr_effect->set_texture("LutTexture", lut_texture == nullptr ? nullptr : ui_lut_texture->get_finaltex());
+ curr_effect->set_texture("LutTexture", !lut_texture ? nullptr : ui_lut_texture->get_finaltex());
blit(nullptr, false, poly->type(), vertnum, poly->count());
}
@@ -2554,7 +2554,7 @@ void uniform::update()
m_shader->set_float("SmoothBorderAmount", options->smooth_border);
break;
case CU_POST_SHADOW_ALPHA:
- m_shader->set_float("ShadowAlpha", shadersys->shadow_texture == nullptr ? 0.0f : options->shadow_mask_alpha);
+ m_shader->set_float("ShadowAlpha", !shadersys->shadow_texture ? 0.0f : options->shadow_mask_alpha);
break;
case CU_POST_SHADOW_COUNT:
{
diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp
index 03b7852f6d9..7b8bd082142 100644
--- a/src/osd/modules/render/drawd3d.cpp
+++ b/src/osd/modules/render/drawd3d.cpp
@@ -513,13 +513,12 @@ d3d_texture_manager::d3d_texture_manager(renderer_d3d9 &d3d, IDirect3D9 *d3dobj)
void d3d_texture_manager::create_resources()
{
m_default_bitmap.allocate(8, 8);
- m_default_bitmap.fill(rgb_t(0xff,0xff,0xff,0xff));
-
if (m_default_bitmap.valid())
{
- render_texinfo texture;
+ m_default_bitmap.fill(rgb_t(0xff,0xff,0xff,0xff));
// fake in the basic data so it looks like it came from render.c
+ render_texinfo texture;
texture.base = m_default_bitmap.raw_pixptr(0);
texture.rowpixels = m_default_bitmap.rowpixels();
texture.width = m_default_bitmap.width();
@@ -552,16 +551,16 @@ uint32_t d3d_texture_manager::texture_compute_hash(const render_texinfo *texture
texture_info *d3d_texture_manager::find_texinfo(const render_texinfo *texinfo, uint32_t flags)
{
- uint32_t hash = texture_compute_hash(texinfo, flags);
+ const uint32_t hash = texture_compute_hash(texinfo, flags);
// find a match
for (auto it = m_texture_list.begin(); it != m_texture_list.end(); it++)
{
- auto test_screen = (uint32_t)((*it)->get_texinfo().unique_id >> 57);
- uint32_t test_page = (uint32_t)((*it)->get_texinfo().unique_id >> 56) & 1;
- auto 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)
+ const uint32_t test_screen = uint32_t((*it)->get_texinfo().unique_id >> 57);
+ const uint32_t test_page = uint32_t((*it)->get_texinfo().unique_id >> 56) & 1;
+ const uint32_t prim_screen = uint32_t(texinfo->unique_id >> 57);
+ const uint32_t prim_page = uint32_t(texinfo->unique_id >> 56) & 1;
+ if ((test_screen != prim_screen) || (test_page != prim_page))
continue;
if ((*it)->get_hash() == hash &&
@@ -687,7 +686,7 @@ void d3d_texture_manager::update_textures()
texture_info *texture = find_texinfo(&prim.texture, prim.flags);
if (texture == nullptr)
{
- int prescale = m_renderer.get_shaders()->enabled() ? 1 : m_renderer.window().prescale();
+ const int prescale = m_renderer.get_shaders()->enabled() ? 1 : m_renderer.window().prescale();
auto tex = std::make_unique<texture_info>(*this, &prim.texture, prescale, prim.flags);
texture = tex.get();
@@ -706,9 +705,7 @@ void d3d_texture_manager::update_textures()
}
if (!m_renderer.get_shaders()->enabled())
- {
return;
- }
int screen_index = 0;
for (render_primitive &prim : *m_renderer.window().m_primlist)
@@ -1969,11 +1966,9 @@ texture_info::texture_info(d3d_texture_manager &manager, const render_texinfo* t
, m_flags(flags)
, m_texinfo(*texsource)
, m_type(!PRIMFLAG_GET_SCREENTEX(flags) ? TEXTURE_TYPE_PLAIN : TEXTURE_TYPE_DYNAMIC) // required to compute texture size
- , m_xprescale(prescale)
- , m_yprescale(prescale)
+ , m_xprescale(PRIMFLAG_GET_SCREENTEX(flags) ? prescale : 1)
+ , m_yprescale(PRIMFLAG_GET_SCREENTEX(flags) ? prescale : 1)
{
- HRESULT result;
-
// compute the size
compute_size(texsource->width, texsource->height);
@@ -1981,7 +1976,7 @@ texture_info::texture_info(d3d_texture_manager &manager, const render_texinfo* t
{
// non-screen textures are easy
assert(PRIMFLAG_TEXFORMAT(flags) != TEXFORMAT_YUY16);
- result = m_renderer.get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_d3dtex, nullptr);
+ const HRESULT result = m_renderer.get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_d3dtex, nullptr);
if (FAILED(result))
goto error;
@@ -1990,12 +1985,11 @@ texture_info::texture_info(d3d_texture_manager &manager, const render_texinfo* t
else
{
// screen textures are allocated differently
- D3DFORMAT format;
- DWORD usage = D3DUSAGE_DYNAMIC;
- D3DPOOL pool = D3DPOOL_DEFAULT;
- int maxdim = std::max(m_renderer.get_presentation()->BackBufferWidth, m_renderer.get_presentation()->BackBufferHeight);
// pick the format
+ const DWORD usage = D3DUSAGE_DYNAMIC;
+ const D3DPOOL pool = D3DPOOL_DEFAULT;
+ D3DFORMAT format;
if (PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_YUY16)
format = m_texture_manager.get_yuv_format();
else if (PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_ARGB32)
@@ -2004,35 +1998,29 @@ texture_info::texture_info(d3d_texture_manager &manager, const render_texinfo* t
format = m_renderer.get_screen_format();
// don't prescale above screen size
- while (m_xprescale > 1 && m_rawdims.c.x * m_xprescale >= 2 * maxdim)
- {
+ const int maxdim = std::max(
+ m_renderer.get_presentation()->BackBufferWidth,
+ m_renderer.get_presentation()->BackBufferHeight);
+
+ while ((m_xprescale > 1) && ((m_rawdims.c.x * m_xprescale) >= (2 * maxdim)))
m_xprescale--;
- }
- while (m_xprescale > 1 && m_rawdims.c.x * m_xprescale > manager.get_max_texture_width())
- {
+ while ((m_xprescale > 1) && ((m_rawdims.c.x * m_xprescale) > manager.get_max_texture_width()))
m_xprescale--;
- }
- while (m_yprescale > 1 && m_rawdims.c.y * m_yprescale >= 2 * maxdim)
- {
+
+ while ((m_yprescale > 1) && ((m_rawdims.c.y * m_yprescale) >= (2 * maxdim)))
m_yprescale--;
- }
- while (m_yprescale > 1 && m_rawdims.c.y * m_yprescale > manager.get_max_texture_height())
- {
+ while ((m_yprescale > 1) && ((m_rawdims.c.y * m_yprescale) > manager.get_max_texture_height()))
m_yprescale--;
- }
const int prescale = m_renderer.window().prescale();
- if (m_xprescale != prescale || m_yprescale != prescale)
+ if ((m_xprescale != prescale) || (m_yprescale != prescale))
osd_printf_verbose("Direct3D: adjusting prescale from %dx%d to %dx%d\n", prescale, prescale, m_xprescale, m_yprescale);
// loop until we allocate something or error
+ HRESULT result;
for (int attempt = 0; attempt < 2; attempt++)
{
- // second attempt is always 1:1
- if (attempt == 1)
- m_xprescale = m_yprescale = 1;
-
- if (m_xprescale == 1 && m_yprescale == 1)
+ if ((m_xprescale == 1) && (m_yprescale == 1))
{
// screen textures with no prescaling are pretty easy
result = m_renderer.get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
@@ -2046,26 +2034,33 @@ texture_info::texture_info(d3d_texture_manager &manager, const render_texinfo* t
{
// screen textures with prescaling require two allocations
result = m_renderer.get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
- if (FAILED(result))
- continue;
-
- // for the target surface, we allocate a render target texture
- const int scwidth = m_rawdims.c.x * m_xprescale;
- const int scheight = m_rawdims.c.y * m_yprescale;
+ if (result == D3D_OK)
+ {
+ // for the target surface, we allocate a render target texture
+ const int scwidth = m_rawdims.c.x * m_xprescale;
+ const int scheight = m_rawdims.c.y * m_yprescale;
- // target surfaces typically cannot be YCbCr, so we always pick RGB in that case
- const D3DFORMAT finalfmt = (format != m_texture_manager.get_yuv_format()) ? format : D3DFMT_A8R8G8B8;
+ // target surfaces typically cannot be YCbCr, so we always pick RGB in that case
+ const D3DFORMAT finalfmt = (format != m_texture_manager.get_yuv_format()) ? format : D3DFMT_A8R8G8B8;
- result = m_renderer.get_device()->CreateTexture(scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &m_d3dfinaltex, nullptr);
- if (result == D3D_OK)
- break;
+ result = m_renderer.get_device()->CreateTexture(scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &m_d3dfinaltex, nullptr);
+ if (result == D3D_OK)
+ break;
- m_d3dtex.Reset();
+ m_d3dtex.Reset();
+ }
}
+
+ // second attempt is always 1:1
+ m_xprescale = m_yprescale = 1;
}
+ if (FAILED(result))
+ goto error;
}
// copy the data to the texture
+ assert(m_d3dtex);
+ assert(m_d3dfinaltex);
set_data(texsource, flags);
return;
@@ -2452,12 +2447,17 @@ void texture_info::set_data(const render_texinfo *texsource, uint32_t flags)
void texture_info::prescale()
{
- HRESULT result;
- int i;
-
// if we don't need to, just skip it
- if (m_d3dtex == m_d3dfinaltex)
+ if (m_d3dtex.Get() == m_d3dfinaltex.Get())
+ {
+ assert(m_xprescale == 1);
+ assert(m_yprescale == 1);
return;
+ }
+
+ assert(m_d3dtex);
+ assert((m_xprescale > 1) || (m_yprescale > 1));
+ HRESULT result;
// for all cases, we need to get the surface of the render target
Microsoft::WRL::ComPtr<IDirect3DSurface9> scale_surface;
@@ -2466,7 +2466,6 @@ void texture_info::prescale()
osd_printf_verbose("Direct3D: Error %08lX during texture GetSurfaceLevel call\n", result);
// if we have an offscreen plain surface, we can just StretchRect to it
- assert(m_d3dtex);
// first remember the original render target and set the new one
Microsoft::WRL::ComPtr<IDirect3DSurface9> backbuffer;
@@ -2517,7 +2516,7 @@ void texture_info::prescale()
lockedbuf[3].v0 = (float)(m_texinfo.height + 2 * m_yborderpix) / (float)m_rawdims.c.y;
// reset the remaining vertex parameters
- for (i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++)
{
lockedbuf[i].z = 0.0f;
lockedbuf[i].rhw = 1.0f;