} else {
freertgbuffer(0, getrtgbuffer(0, &avioutput_width, &avioutput_height, &pitch, &avioutput_bits, NULL));
}
- aviout_width_out = avioutput_width + 15;
- aviout_width_out &= ~15;
- aviout_height_out = avioutput_height + 1;
- aviout_height_out &= ~1;
}
if (avioutput_width == 0 || avioutput_height == 0 || avioutput_bits == 0) {
avioutput_width = WIN32GFX_GetWidth(mon);
avioutput_height = WIN32GFX_GetHeight(mon);
avioutput_bits = WIN32GFX_GetDepth(mon, 0);
+ if (WIN32GFX_IsPicassoScreen(mon) && avioutput_originalsize) {
+ struct picasso96_state_struct *state = &picasso96_state[aviout_monid];
+ avioutput_width = state->Width;
+ avioutput_height = state->Height;
+ }
}
+ aviout_width_out = avioutput_width + 15;
+ aviout_width_out &= ~15;
+ aviout_height_out = avioutput_height + 1;
+ aviout_height_out &= ~1;
+
AVIOutput_Initialize ();
AVIOutput_ReleaseVideo ();
if (avioutput_width == 0 || avioutput_height == 0) {
fwrite (sndbuffer, 1, sndbufsize, wavfile);
}
-static int getFromRenderTarget11(struct avientry *avie)
+static int getFromRenderTarget11(struct avientry *avie, bool renderTarget)
{
int ok = 0;
int w, h, pitch, bits = 32;
void *data;
- bool got = D3D11_capture(aviout_monid, &data, &w, &h, &pitch);
+ bool got = D3D11_capture(aviout_monid, &data, &w, &h, &pitch, renderTarget);
if (got) {
int dpitch = ((aviout_width_out * avioutput_bits + 31) & ~31) / 8;
- for (int y = 0; y < h; y++) {
- uae_u8 *d = (uae_u8*)avie->lpVideo + (h - y - 1) * dpitch;
+ for (int y = 0; y < h && y < aviout_height_out; y++) {
+ uae_u8 *d = (uae_u8*)avie->lpVideo + (aviout_height_out - y - 1) * dpitch;
uae_u32 *s = (uae_u32*)((uae_u8*)data + y * pitch);
- for (int x = 0; x < w; x++) {
+ for (int x = 0; x < w && x < aviout_width_out; x++) {
uae_u32 v = *s++;
d[0] = v >> 0;
d[1] = v >> 8;
}
}
}
- D3D11_capture(aviout_monid, NULL, NULL, NULL, NULL);
+ D3D11_capture(aviout_monid, NULL, NULL, NULL, NULL, renderTarget);
ok = 1;
}
return ok;
}
-static int getFromRenderTarget(struct avientry *avie)
+static int getFromRenderTarget(struct avientry *avie, bool renderTarget)
{
int ok = 0;
int w, h, bits;
HRESULT hr;
D3DLOCKED_RECT l;
- LPDIRECT3DSURFACE9 s = D3D_capture(aviout_monid, &w, &h, &bits);
+ LPDIRECT3DSURFACE9 s = D3D_capture(aviout_monid, &w, &h, &bits, renderTarget);
if (s) {
hr = s->LockRect(&l, NULL, D3DLOCK_READONLY);
if (SUCCEEDED(hr)) {
int dpitch = ((aviout_width_out * avioutput_bits + 31) & ~31) / 8;
if (bits == 32) {
- for (int y = 0; y < h; y++) {
- uae_u8 *d = (uae_u8*)avie->lpVideo + (h - y - 1) * dpitch;
+ for (int y = 0; y < h && y < aviout_height_out; y++) {
+ uae_u8 *d = (uae_u8*)avie->lpVideo + (aviout_height_out - y - 1) * dpitch;
uae_u32 *s = (uae_u32*)((uae_u8*)l.pBits + y * l.Pitch);
- for (int x = 0; x < w; x++) {
+ for (int x = 0; x < w && x < aviout_width_out; x++) {
uae_u32 v = *s++;
d[0] = v >> 0;
d[1] = v >> 8;
}
}
} else if (bits == 16 || bits == 15) {
- for (int y = 0; y < h; y++) {
- uae_u8 *d = (uae_u8*)avie->lpVideo + (h - y - 1) * dpitch;
+ for (int y = 0; y < h && y < aviout_height_out; y++) {
+ uae_u8 *d = (uae_u8*)avie->lpVideo + (aviout_height_out - y - 1) * dpitch;
uae_u16 *s = (uae_u16*)((uae_u8*)l.pBits + y * l.Pitch);
- for (int x = 0; x < w; x++) {
+ for (int x = 0; x < w && x < aviout_width_out; x++) {
uae_u16 v = s[x];
uae_u16 v2 = v;
if (bits == 16) {
dorestart ();
waitqueuefull ();
ae = allocavientry_video();
+ lockrtg();
if (avioutput_originalsize || WIN32GFX_IsPicassoScreen(mon)) {
v = getFromBuffer (ae, 1);
+ if (!v) {
+ if (D3D_isenabled(0) == 2) {
+ v = getFromRenderTarget11(ae, false);
+ } else if (D3D_isenabled(0) == 1) {
+ v = getFromRenderTarget(ae, false);
+ }
+ }
} else {
if (D3D_isenabled(0) == 2) {
- v = getFromRenderTarget11(ae);
+ v = getFromRenderTarget11(ae, true);
} else if (D3D_isenabled(0) == 1) {
- v = getFromRenderTarget(ae);
+ v = getFromRenderTarget(ae, true);
} else {
v = getFromDC (ae);
}
}
+ unlockrtg();
if (v)
queueavientry (ae);
else
#include "direct3d.h"
static TCHAR *D3DHEAD = _T("-");
-static struct gfx_filterdata *filterd3d;
-static int filterd3didx;
static bool showoverlay = true;
static int slicecnt;
bool cursor_v, cursor_scale;
int statusbar_vx, statusbar_hx;
+ struct gfx_filterdata *filterd3d;
+ int filterd3didx;
+ int scanline_osl1, scanline_osl2, scanline_osl3;
+
D3DXHANDLE postSourceTextureHandle;
D3DXHANDLE postMaskTextureHandle;
D3DXHANDLE postTechnique, postTechniquePlain, postTechniqueAlpha;
{
HRESULT hr;
D3DLOCKED_RECT locked;
- static int osl1, osl2, osl3;
int sl4, sl42;
int l1, l2;
int x, y, yy;
uae_u8 *sld, *p;
int bpp;
- if (osl1 == filterd3d->gfx_filter_scanlines && osl3 == filterd3d->gfx_filter_scanlinelevel && osl2 == filterd3d->gfx_filter_scanlineratio && !force)
+ if (d3d->scanline_osl1 == d3d->filterd3d->gfx_filter_scanlines &&
+ d3d->scanline_osl3 == d3d->filterd3d->gfx_filter_scanlinelevel &&
+ d3d->scanline_osl2 == d3d->filterd3d->gfx_filter_scanlineratio && !force)
return;
bpp = d3d->t_depth < 32 ? 2 : 4;
- osl1 = filterd3d->gfx_filter_scanlines;
- osl3 = filterd3d->gfx_filter_scanlinelevel;
- osl2 = filterd3d->gfx_filter_scanlineratio;
- sl4 = filterd3d->gfx_filter_scanlines * 16 / 100;
- sl42 = filterd3d->gfx_filter_scanlinelevel * 16 / 100;
+ d3d->scanline_osl1 = d3d->filterd3d->gfx_filter_scanlines;
+ d3d->scanline_osl3 = d3d->filterd3d->gfx_filter_scanlinelevel;
+ d3d->scanline_osl2 = d3d->filterd3d->gfx_filter_scanlineratio;
+ sl4 = d3d->filterd3d->gfx_filter_scanlines * 16 / 100;
+ sl42 = d3d->filterd3d->gfx_filter_scanlinelevel * 16 / 100;
if (sl4 > 15)
sl4 = 15;
if (sl42 > 15)
sl42 = 15;
- l1 = (filterd3d->gfx_filter_scanlineratio >> 0) & 15;
- l2 = (filterd3d->gfx_filter_scanlineratio >> 4) & 15;
+ l1 = (d3d->filterd3d->gfx_filter_scanlineratio >> 0) & 15;
+ l2 = (d3d->filterd3d->gfx_filter_scanlineratio >> 4) & 15;
if (l1 + l2 <= 0)
return;
if (!d3d->sltexture) {
- if (osl1 == 0 && osl3 == 0)
+ if (d3d->scanline_osl1 == 0 && d3d->scanline_osl3 == 0)
return;
if (!createsltexture (d3d))
return;
{
struct AmigaMonitor *mon = &AMonitors[d3d - d3ddata];
struct zfile *zf;
- int size;
LPDIRECT3DTEXTURE9 tx;
HRESULT hr;
TCHAR tmp[MAX_DPATH];
break;
}
for (int i = 0; i < MAX_FILTERSHADERS; i++) {
- if (filterd3d->gfx_filtershader[i][0]) {
+ if (d3d->filterd3d->gfx_filtershader[i][0]) {
struct shaderdata *s = allocshaderslot (d3d, SHADERTYPE_BEFORE);
- if (!psEffect_LoadEffect (d3d, filterd3d->gfx_filtershader[i], true, s, i)) {
- filterd3d->gfx_filtershader[i][0] = changed_prefs.gf[filterd3didx].gfx_filtershader[i][0] = 0;
+ if (!psEffect_LoadEffect (d3d, d3d->filterd3d->gfx_filtershader[i], true, s, i)) {
+ d3d->filterd3d->gfx_filtershader[i][0] = changed_prefs.gf[d3d->filterd3didx].gfx_filtershader[i][0] = 0;
break;
}
}
- if (filterd3d->gfx_filtermask[i][0]) {
+ if (d3d->filterd3d->gfx_filtermask[i][0]) {
struct shaderdata *s = allocshaderslot (d3d, SHADERTYPE_MASK_BEFORE);
- createmasktexture (d3d, filterd3d->gfx_filtermask[i], s);
+ createmasktexture (d3d, d3d->filterd3d->gfx_filtermask[i], s);
}
}
- if (filterd3d->gfx_filtershader[2 * MAX_FILTERSHADERS][0]) {
+ if (d3d->filterd3d->gfx_filtershader[2 * MAX_FILTERSHADERS][0]) {
struct shaderdata *s = allocshaderslot (d3d, SHADERTYPE_MIDDLE);
- if (!psEffect_LoadEffect (d3d, filterd3d->gfx_filtershader[2 * MAX_FILTERSHADERS], true, s, 2 * MAX_FILTERSHADERS)) {
- filterd3d->gfx_filtershader[2 * MAX_FILTERSHADERS][0] = changed_prefs.gf[filterd3didx].gfx_filtershader[2 * MAX_FILTERSHADERS][0] = 0;
+ if (!psEffect_LoadEffect (d3d, d3d->filterd3d->gfx_filtershader[2 * MAX_FILTERSHADERS], true, s, 2 * MAX_FILTERSHADERS)) {
+ d3d->filterd3d->gfx_filtershader[2 * MAX_FILTERSHADERS][0] = changed_prefs.gf[d3d->filterd3didx].gfx_filtershader[2 * MAX_FILTERSHADERS][0] = 0;
}
}
- if (filterd3d->gfx_filtermask[2 * MAX_FILTERSHADERS][0]) {
+ if (d3d->filterd3d->gfx_filtermask[2 * MAX_FILTERSHADERS][0]) {
struct shaderdata *s = allocshaderslot (d3d, SHADERTYPE_MASK_AFTER);
- createmasktexture (d3d, filterd3d->gfx_filtermask[2 * MAX_FILTERSHADERS], s);
+ createmasktexture (d3d, d3d->filterd3d->gfx_filtermask[2 * MAX_FILTERSHADERS], s);
}
for (int i = 0; i < MAX_FILTERSHADERS; i++) {
- if (filterd3d->gfx_filtershader[i + MAX_FILTERSHADERS][0]) {
+ if (d3d->filterd3d->gfx_filtershader[i + MAX_FILTERSHADERS][0]) {
struct shaderdata *s = allocshaderslot (d3d, SHADERTYPE_AFTER);
- if (!psEffect_LoadEffect (d3d, filterd3d->gfx_filtershader[i + MAX_FILTERSHADERS], true, s, i + MAX_FILTERSHADERS)) {
- filterd3d->gfx_filtershader[i + MAX_FILTERSHADERS][0] = changed_prefs.gf[filterd3didx].gfx_filtershader[i + MAX_FILTERSHADERS][0] = 0;
+ if (!psEffect_LoadEffect (d3d, d3d->filterd3d->gfx_filtershader[i + MAX_FILTERSHADERS], true, s, i + MAX_FILTERSHADERS)) {
+ d3d->filterd3d->gfx_filtershader[i + MAX_FILTERSHADERS][0] = changed_prefs.gf[d3d->filterd3didx].gfx_filtershader[i + MAX_FILTERSHADERS][0] = 0;
break;
}
}
- if (filterd3d->gfx_filtermask[i + MAX_FILTERSHADERS][0]) {
+ if (d3d->filterd3d->gfx_filtermask[i + MAX_FILTERSHADERS][0]) {
struct shaderdata *s = allocshaderslot (d3d, SHADERTYPE_MASK_AFTER);
- createmasktexture (d3d, filterd3d->gfx_filtermask[i + MAX_FILTERSHADERS], s);
+ createmasktexture (d3d, d3d->filterd3d->gfx_filtermask[i + MAX_FILTERSHADERS], s);
}
}
break;
}
- if (filterd3d->gfx_filter_scanlines > 0) {
+ if (d3d->filterd3d->gfx_filter_scanlines > 0) {
createsltexture(d3d);
createscanlines(d3d, 1);
}
if (wasshader && !shaderon)
write_log (_T("Falling back to non-shader mode\n"));
- createmask2texture (d3d, filterd3d->gfx_filteroverlay);
+ createmask2texture (d3d, d3d->filterd3d->gfx_filteroverlay);
createledtexture (d3d);
struct apmode ap;
D3DADAPTER_IDENTIFIER9 did;
- filterd3didx = ad->picasso_on;
- filterd3d = &currprefs.gf[filterd3didx];
+ d3d->filterd3didx = ad->picasso_on;
+ d3d->filterd3d = &currprefs.gf[d3d->filterd3didx];
D3D_free2 (d3d);
if (!currprefs.gfx_api) {
d3d->required_sl_texture_w = w_w;
d3d->required_sl_texture_h = w_h;
- if (filterd3d->gfx_filter_scanlines > 0 && (d3d->max_texture_w < w_w || d3d->max_texture_h < w_h)) {
+ if (d3d->filterd3d->gfx_filter_scanlines > 0 && (d3d->max_texture_w < w_w || d3d->max_texture_h < w_h)) {
gui_message (_T("%s: %d * %d or bigger texture support required for scanlines (max is only %d * %d)\n"),
D3DHEAD, _T("Scanlines disabled."),
d3d->required_sl_texture_w, d3d->required_sl_texture_h, d3d->max_texture_w, d3d->max_texture_h);
- changed_prefs.gf[filterd3didx].gfx_filter_scanlines = filterd3d->gfx_filter_scanlines = 0;
+ changed_prefs.gf[d3d->filterd3didx].gfx_filter_scanlines = d3d->filterd3d->gfx_filter_scanlines = 0;
}
switch (depth)
hr = d3d->d3ddev->CreateOffscreenPlainSurface(w_w, w_h, d3d->tformat, D3DPOOL_SYSTEMMEM, &d3d->screenshotsurface, NULL);
if (FAILED(hr)) {
- write_log(_T("%s: CreateOffscreenPlainSurface failed: %s\n"), D3DHEAD, D3D_ErrorString(hr));
+ write_log(_T("%s: CreateOffscreenPlainSurface RT failed: %s\n"), D3DHEAD, D3D_ErrorString(hr));
}
return 0;
if (FAILED (hr = postEffect->SetTechnique (d3d->postTechniquePlain)))
write_log (_T("%s: SetTechnique(postTechniquePlain) failed: %s\n"), D3DHEAD, D3D_ErrorString (hr));
}
- hr = postEffect->SetInt (d3d->postFilterMode, filterd3d->gfx_filter_bilinear ? D3DTEXF_LINEAR : D3DTEXF_POINT);
+ hr = postEffect->SetInt (d3d->postFilterMode, d3d->filterd3d->gfx_filter_bilinear ? D3DTEXF_LINEAR : D3DTEXF_POINT);
if (FAILED (hr = postEffect->SetTexture (d3d->postSourceTextureHandle, srctex)))
write_log (_T("%s: SetTexture(srctex) failed: %s\n"), D3DHEAD, D3D_ErrorString (hr));
hr = d3d->d3ddev->SetTransform (D3DTS_WORLD, &d3d->m_matWorld);
hr = d3d->d3ddev->SetTexture (0, srctex);
hr = d3d->d3ddev->DrawPrimitive (D3DPT_TRIANGLESTRIP, 0, 2);
- int bl = filterd3d->gfx_filter_bilinear ? D3DTEXF_LINEAR : D3DTEXF_POINT;
+ int bl = d3d->filterd3d->gfx_filter_bilinear ? D3DTEXF_LINEAR : D3DTEXF_POINT;
hr = d3d->d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, bl);
hr = d3d->d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, bl);
hr = d3d->d3ddev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
MatrixScaling (&t, w, h, 0);
v.x = 0;
- if (filterd3d->gfx_filteroverlay_pos.x == -1)
+ if (d3d->filterd3d->gfx_filteroverlay_pos.x == -1)
v.x = (d3d->window_w - (d3d->mask2texture_w * w)) / 2;
- else if (filterd3d->gfx_filteroverlay_pos.x > -24000)
- v.x = filterd3d->gfx_filteroverlay_pos.x;
+ else if (d3d->filterd3d->gfx_filteroverlay_pos.x > -24000)
+ v.x = d3d->filterd3d->gfx_filteroverlay_pos.x;
else
- v.x = (d3d->window_w - (d3d->mask2texture_w * w)) / 2 + (-filterd3d->gfx_filteroverlay_pos.x - 30100) * d3d->window_w / 100.0;
+ v.x = (d3d->window_w - (d3d->mask2texture_w * w)) / 2 + (-d3d->filterd3d->gfx_filteroverlay_pos.x - 30100) * d3d->window_w / 100.0;
v.y = 0;
- if (filterd3d->gfx_filteroverlay_pos.y == -1)
+ if (d3d->filterd3d->gfx_filteroverlay_pos.y == -1)
v.y = (d3d->window_h - (d3d->mask2texture_h * h)) / 2;
- else if (filterd3d->gfx_filteroverlay_pos.y > -24000)
- v.y = filterd3d->gfx_filteroverlay_pos.y;
+ else if (d3d->filterd3d->gfx_filteroverlay_pos.y > -24000)
+ v.y = d3d->filterd3d->gfx_filteroverlay_pos.y;
else
- v.y = (d3d->window_h - (d3d->mask2texture_h * h)) / 2 + (-filterd3d->gfx_filteroverlay_pos.y - 30100) * d3d->window_h / 100.0;
+ v.y = (d3d->window_h - (d3d->mask2texture_h * h)) / 2 + (-d3d->filterd3d->gfx_filteroverlay_pos.y - 30100) * d3d->window_h / 100.0;
v.x /= w;
v.y /= h;
d3d->guimode = guion;
}
-LPDIRECT3DSURFACE9 D3D_capture(int monid, int *w, int *h, int *bits)
+LPDIRECT3DSURFACE9 D3D_capture(int monid, int *w, int *h, int *bits, bool rendertarget)
{
struct d3dstruct *d3d = &d3ddata[monid];
- LPDIRECT3DSURFACE9 rt;
HRESULT hr;
+ LPDIRECT3DSURFACE9 ret = NULL;
waitfakemode(d3d);
if (!isd3d(d3d))
return NULL;
- hr = d3d->d3ddev->GetRenderTarget(0, &rt);
- if (FAILED(hr)) {
- write_log(_T("%s: GetRenderTarget() failed: %s\n"), D3DHEAD, D3D_ErrorString(hr));
- return NULL;
- }
- hr = d3d->d3ddev->GetRenderTargetData(rt, d3d->screenshotsurface);
- rt->Release();
- if (FAILED(hr)) {
- write_log(_T("%s: GetRenderTargetData() failed: %s\n"), D3DHEAD, D3D_ErrorString(hr));
- return NULL;
+ if (rendertarget) {
+ LPDIRECT3DSURFACE9 rt;
+ hr = d3d->d3ddev->GetRenderTarget(0, &rt);
+ if (FAILED(hr)) {
+ write_log(_T("%s: D3D_capture() GetRenderTarget() failed: %s\n"), D3DHEAD, D3D_ErrorString(hr));
+ return NULL;
+ }
+ hr = d3d->d3ddev->GetRenderTargetData(rt, d3d->screenshotsurface);
+ rt->Release();
+ if (FAILED(hr)) {
+ write_log(_T("%s: D3D_capture() GetRenderTargetData() failed: %s\n"), D3DHEAD, D3D_ErrorString(hr));
+ return NULL;
+ }
+ ret = d3d->screenshotsurface;
+ } else {
+ hr = d3d->texture->GetSurfaceLevel(0, &ret);
+ if (FAILED(hr)) {
+ write_log(_T("%s: D3D_capture() GetSurfaceLevel() failed: %s\n"), D3DHEAD, D3D_ErrorString(hr));
+ return NULL;
+ }
}
*w = d3d->window_w;
*h = d3d->window_h;
*bits = d3d->t_depth;
- return d3d->screenshotsurface;
+ return ret;
}
static HDC xD3D_getDC(int monid, HDC hdc)
extern void(*D3D_led)(int, int, int);
extern bool(*D3D_getscanline)(int*, bool*);
-extern LPDIRECT3DSURFACE9 D3D_capture(int, int*,int*,int*);
-extern bool D3D11_capture(int, void**,int*, int*,int*);
+extern LPDIRECT3DSURFACE9 D3D_capture(int, int*,int*,int*,bool);
+extern bool D3D11_capture(int, void**,int*, int*,int*,bool);
void D3D_getpixelformat(int depth, int *rb, int *gb, int *bb, int *rs, int *gs, int *bs, int *ab, int *as, int *a);
static int d3d11_feature_level;
-static struct gfx_filterdata *filterd3d;
-static int filterd3didx;
static int leds[LED_MAX];
static int debugcolors;
static bool cannoclear;
ID3D11ShaderResourceView *sltexturerv;
ID3D11Texture2D *texture2d, *texture2dstaging;
ID3D11Texture2D *sltexture;
- ID3D11Texture2D *screenshottexture;
+ ID3D11Texture2D *screenshottexturert, *screenshottexturetx;
ID3D11VertexShader *m_vertexShader;
ID3D11PixelShader *m_pixelShader, *m_pixelShaderSL, *m_pixelShaderMask;
ID3D11SamplerState *m_sampleState_point_clamp, *m_sampleState_linear_clamp;
float cursor_x, cursor_y;
bool cursor_v, cursor_scale;
+ struct gfx_filterdata *filterd3d;
+ int filterd3didx;
+ int scanline_osl1, scanline_osl2, scanline_osl3;
+
struct shaderdata11 shaders[MAX_SHADERS];
ID3DX11EffectTechnique *technique;
ID3DX11EffectPass *effectpass;
{
FreeTexture2D(&d3d->texture2d, &d3d->texture2drv);
FreeTexture2D(&d3d->texture2dstaging, NULL);
- FreeTexture2D(&d3d->screenshottexture, NULL);
+ FreeTexture2D(&d3d->screenshottexturetx, NULL);
+ FreeTexture2D(&d3d->screenshottexturert, NULL);
freesprite(&d3d->osd);
freesprite(&d3d->hwsprite);
return false;
}
+ desc.Width = d3d->m_screenWidth;
+ desc.Height = d3d->m_screenHeight;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ hr = d3d->m_device->CreateTexture2D(&desc, nullptr, &d3d->screenshottexturetx);
+ if (FAILED(hr)) {
+ write_log(_T("CreateTexture2D (screenshot tx) failed: %08x\n"), hr);
+ }
+
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MostDetailedMip = 0;
srvDesc.Texture2D.MipLevels = desc.MipLevels;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.Usage = D3D11_USAGE_STAGING;
- hr = d3d->m_device->CreateTexture2D(&desc, nullptr, &d3d->screenshottexture);
+ hr = d3d->m_device->CreateTexture2D(&desc, nullptr, &d3d->screenshottexturert);
if (FAILED(hr)) {
- write_log(_T("CreateTexture2D (screenshot) failed: %08x\n"), hr);
+ write_log(_T("CreateTexture2D (screenshot rt) failed: %08x\n"), hr);
}
pSurface->Release();
}
{
HRESULT hr;
D3D11_MAPPED_SUBRESOURCE map;
- static int osl1, osl2, osl3;
int sl4, sl42;
int l1, l2;
int x, y, yy;
uae_u8 *sld, *p;
int bpp;
- if (osl1 == filterd3d->gfx_filter_scanlines && osl3 == filterd3d->gfx_filter_scanlinelevel && osl2 == filterd3d->gfx_filter_scanlineratio && !force)
+ if (d3d->scanline_osl1 == d3d->filterd3d->gfx_filter_scanlines &&
+ d3d->scanline_osl3 == d3d->filterd3d->gfx_filter_scanlinelevel &&
+ d3d->scanline_osl2 == d3d->filterd3d->gfx_filter_scanlineratio && !force)
return;
bpp = 4;
- osl1 = filterd3d->gfx_filter_scanlines;
- osl3 = filterd3d->gfx_filter_scanlinelevel;
- osl2 = filterd3d->gfx_filter_scanlineratio;
- sl4 = filterd3d->gfx_filter_scanlines * 16 / 100;
- sl42 = filterd3d->gfx_filter_scanlinelevel * 16 / 100;
+ d3d->scanline_osl1 = d3d->filterd3d->gfx_filter_scanlines;
+ d3d->scanline_osl3 = d3d->filterd3d->gfx_filter_scanlinelevel;
+ d3d->scanline_osl2 = d3d->filterd3d->gfx_filter_scanlineratio;
+ sl4 = d3d->filterd3d->gfx_filter_scanlines * 16 / 100;
+ sl42 = d3d->filterd3d->gfx_filter_scanlinelevel * 16 / 100;
if (sl4 > 15)
sl4 = 15;
if (sl42 > 15)
sl42 = 15;
- l1 = (filterd3d->gfx_filter_scanlineratio >> 0) & 15;
- l2 = (filterd3d->gfx_filter_scanlineratio >> 4) & 15;
+ l1 = (d3d->filterd3d->gfx_filter_scanlineratio >> 0) & 15;
+ l2 = (d3d->filterd3d->gfx_filter_scanlineratio >> 4) & 15;
if (l1 + l2 <= 0)
return;
if (!d3d->sltexture) {
- if (osl1 == 0 && osl3 == 0)
+ if (d3d->scanline_osl1 == 0 && d3d->scanline_osl3 == 0)
return;
if (!createsltexture(d3d))
return;
write_log(_T("D3D11 init start. (%d*%d) (%d*%d) RTG=%d Depth=%d.\n"), w_w, w_h, t_w, t_h, ad->picasso_on, depth);
- filterd3didx = ad->picasso_on;
- filterd3d = &currprefs.gf[filterd3didx];
+ d3d->filterd3didx = ad->picasso_on;
+ d3d->filterd3d = &currprefs.gf[d3d->filterd3didx];
d3d->delayedfs = 0;
d3d->device_errors = 0;
}
// Set the sampler state in the pixel shader.
- d3d->m_deviceContext->PSSetSamplers(0, 1, filterd3d->gfx_filter_bilinear ? &d3d->m_sampleState_linear_clamp : &d3d->m_sampleState_point_clamp);
- d3d->m_deviceContext->PSSetSamplers(1, 1, filterd3d->gfx_filter_bilinear ? &d3d->m_sampleState_linear_wrap : &d3d->m_sampleState_point_wrap);
+ d3d->m_deviceContext->PSSetSamplers(0, 1, d3d->filterd3d->gfx_filter_bilinear ? &d3d->m_sampleState_linear_clamp : &d3d->m_sampleState_point_clamp);
+ d3d->m_deviceContext->PSSetSamplers(1, 1, d3d->filterd3d->gfx_filter_bilinear ? &d3d->m_sampleState_linear_wrap : &d3d->m_sampleState_point_wrap);
// Render the triangle.
d3d->m_deviceContext->DrawIndexed(INDEXCOUNT, 0, 0);
static bool restore(struct d3d11struct *d3d)
{
for (int i = 0; i < MAX_FILTERSHADERS; i++) {
- if (filterd3d->gfx_filtershader[i][0]) {
+ if (d3d->filterd3d->gfx_filtershader[i][0]) {
struct shaderdata11 *s = allocshaderslot(d3d, SHADERTYPE_BEFORE);
- if (!psEffect_LoadEffect(d3d, filterd3d->gfx_filtershader[i], s, i)) {
+ if (!psEffect_LoadEffect(d3d, d3d->filterd3d->gfx_filtershader[i], s, i)) {
freeshaderdata(s);
- filterd3d->gfx_filtershader[i][0] = changed_prefs.gf[filterd3didx].gfx_filtershader[i][0] = 0;
+ d3d->filterd3d->gfx_filtershader[i][0] = changed_prefs.gf[d3d->filterd3didx].gfx_filtershader[i][0] = 0;
break;
}
}
- if (filterd3d->gfx_filtermask[i][0]) {
+ if (d3d->filterd3d->gfx_filtermask[i][0]) {
struct shaderdata11 *s = allocshaderslot(d3d, SHADERTYPE_MASK_BEFORE);
- if (!createmasktexture(d3d, filterd3d->gfx_filtermask[i], s)) {
+ if (!createmasktexture(d3d, d3d->filterd3d->gfx_filtermask[i], s)) {
freeshaderdata(s);
}
}
}
- if (filterd3d->gfx_filtershader[2 * MAX_FILTERSHADERS][0]) {
+ if (d3d->filterd3d->gfx_filtershader[2 * MAX_FILTERSHADERS][0]) {
struct shaderdata11 *s = allocshaderslot(d3d, SHADERTYPE_MIDDLE);
- if (!psEffect_LoadEffect(d3d, filterd3d->gfx_filtershader[2 * MAX_FILTERSHADERS], s, 2 * MAX_FILTERSHADERS)) {
+ if (!psEffect_LoadEffect(d3d, d3d->filterd3d->gfx_filtershader[2 * MAX_FILTERSHADERS], s, 2 * MAX_FILTERSHADERS)) {
freeshaderdata(s);
- filterd3d->gfx_filtershader[2 * MAX_FILTERSHADERS][0] = changed_prefs.gf[filterd3didx].gfx_filtershader[2 * MAX_FILTERSHADERS][0] = 0;
+ d3d->filterd3d->gfx_filtershader[2 * MAX_FILTERSHADERS][0] = changed_prefs.gf[d3d->filterd3didx].gfx_filtershader[2 * MAX_FILTERSHADERS][0] = 0;
}
}
- if (filterd3d->gfx_filtermask[2 * MAX_FILTERSHADERS][0]) {
+ if (d3d->filterd3d->gfx_filtermask[2 * MAX_FILTERSHADERS][0]) {
struct shaderdata11 *s = allocshaderslot(d3d, SHADERTYPE_MASK_AFTER);
- if (!createmasktexture(d3d, filterd3d->gfx_filtermask[2 * MAX_FILTERSHADERS], s)) {
+ if (!createmasktexture(d3d, d3d->filterd3d->gfx_filtermask[2 * MAX_FILTERSHADERS], s)) {
freeshaderdata(s);
}
}
for (int i = 0; i < MAX_FILTERSHADERS; i++) {
- if (filterd3d->gfx_filtershader[i + MAX_FILTERSHADERS][0]) {
+ if (d3d->filterd3d->gfx_filtershader[i + MAX_FILTERSHADERS][0]) {
struct shaderdata11 *s = allocshaderslot(d3d, SHADERTYPE_AFTER);
- if (!psEffect_LoadEffect(d3d, filterd3d->gfx_filtershader[i + MAX_FILTERSHADERS], s, i + MAX_FILTERSHADERS)) {
+ if (!psEffect_LoadEffect(d3d, d3d->filterd3d->gfx_filtershader[i + MAX_FILTERSHADERS], s, i + MAX_FILTERSHADERS)) {
freeshaderdata(s);
- filterd3d->gfx_filtershader[i + MAX_FILTERSHADERS][0] = changed_prefs.gf[filterd3didx].gfx_filtershader[i + MAX_FILTERSHADERS][0] = 0;
+ d3d->filterd3d->gfx_filtershader[i + MAX_FILTERSHADERS][0] = changed_prefs.gf[d3d->filterd3didx].gfx_filtershader[i + MAX_FILTERSHADERS][0] = 0;
break;
}
}
- if (filterd3d->gfx_filtermask[i + MAX_FILTERSHADERS][0]) {
+ if (d3d->filterd3d->gfx_filtermask[i + MAX_FILTERSHADERS][0]) {
struct shaderdata11 *s = allocshaderslot(d3d, SHADERTYPE_MASK_AFTER);
- if (!createmasktexture(d3d, filterd3d->gfx_filtermask[i + MAX_FILTERSHADERS], s)) {
+ if (!createmasktexture(d3d, d3d->filterd3d->gfx_filtermask[i + MAX_FILTERSHADERS], s)) {
freeshaderdata(s);
}
}
createscanlines(d3d, 1);
- createmask2texture(d3d, filterd3d->gfx_filteroverlay);
+ createmask2texture(d3d, d3d->filterd3d->gfx_filteroverlay);
int w = d3d->m_bitmapWidth;
int h = d3d->m_bitmapHeight;
}
}
-bool D3D11_capture(int monid, void **data, int *w, int *h, int *pitch)
+bool D3D11_capture(int monid, void **data, int *w, int *h, int *pitch, bool rendertarget)
{
struct d3d11struct *d3d = &d3d11data[monid];
HRESULT hr;
+ ID3D11Texture2D *screenshottexture = rendertarget ? d3d->screenshottexturert : d3d->screenshottexturetx;
- if (!d3d->screenshottexture)
+ if (!screenshottexture)
return false;
if (!w || !h) {
- d3d->m_deviceContext->Unmap(d3d->screenshottexture, 0);
+ d3d->m_deviceContext->Unmap(screenshottexture, 0);
return true;
} else {
D3D11_MAPPED_SUBRESOURCE map;
ID3D11Resource* pSurface = NULL;
- d3d->m_renderTargetView->GetResource(&pSurface);
+ ID3D11Resource* pSurfaceRelease = NULL;
+ if (rendertarget) {
+ d3d->m_renderTargetView->GetResource(&pSurface);
+ pSurfaceRelease = pSurface;
+ } else {
+ pSurface = d3d->texture2dstaging;
+ }
if (pSurface) {
- d3d->m_deviceContext->CopyResource(d3d->screenshottexture, pSurface);
D3D11_TEXTURE2D_DESC desc;
- d3d->screenshottexture->GetDesc(&desc);
- hr = d3d->m_deviceContext->Map(d3d->screenshottexture, 0, D3D11_MAP_READ, 0, &map);
+ d3d->m_deviceContext->CopyResource(screenshottexture, pSurface);
+ screenshottexture->GetDesc(&desc);
+ hr = d3d->m_deviceContext->Map(screenshottexture, 0, D3D11_MAP_READ, 0, &map);
if (FAILED(hr)) {
write_log(_T("Screenshot DeviceContext->Map() failed %08x\n"), hr);
return false;
}
- pSurface->Release();
+ if (pSurfaceRelease) {
+ pSurfaceRelease->Release();
+ }
*data = map.pData;
*pitch = map.RowPitch;
*w = desc.Width;
#include "drawing.h"
#include "fsdb.h"
#include "zfile.h"
+#include "picasso96_win.h"
#include "png.h"
HGDIOBJ hgdiobj;
int bits;
int depth = usealpha() ? 32 : 24;
+ bool renderTarget = true;
+
+ lockrtg();
screenshot_free ();
rgb_rs2 = rgb_rs;
rgb_as2 = rgb_as;
}
- if (src == NULL)
+ if (src == NULL) {
+ if (WIN32GFX_IsPicassoScreen(mon))
+ renderTarget = false;
goto donormal;
+ }
if (width == 0 || height == 0) {
if (needfree) {
if (WIN32GFX_IsPicassoScreen(mon))
bool d3dcaptured = false;
width = WIN32GFX_GetWidth(mon);
height = WIN32GFX_GetHeight(mon);
-
+ if (!renderTarget && WIN32GFX_IsPicassoScreen(mon)) {
+ struct picasso96_state_struct *state = &picasso96_state[monid];
+ width = state->Width;
+ height = state->Height;
+ }
if (D3D_isenabled(0) == 2) {
int w, h, pitch, bits = 32;
void *data;
- bool got = D3D11_capture(monid, &data, &w, &h, &pitch);
+ bool got = D3D11_capture(monid, &data, &w, &h, &pitch, renderTarget);
- int dpitch = (((w * depth + 31) & ~31) / 8);
- lpvBits = xmalloc(uae_u8, dpitch * h);
+ int dpitch = (((width * depth + 31) & ~31) / 8);
+ lpvBits = xmalloc(uae_u8, dpitch * height);
ZeroMemory(bi, sizeof(bi));
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bi->bmiHeader.biWidth = w;
- bi->bmiHeader.biHeight = h;
+ bi->bmiHeader.biWidth = width;
+ bi->bmiHeader.biHeight = height;
bi->bmiHeader.biPlanes = 1;
bi->bmiHeader.biBitCount = depth;
bi->bmiHeader.biCompression = BI_RGB;
bi->bmiHeader.biClrImportant = 0;
if (got && lpvBits) {
- for (int y = 0; y < h; y++) {
- uae_u8 *d = (uae_u8*)lpvBits + (h - y - 1) * dpitch;
+ for (int y = 0; y < h && y < height; y++) {
+ uae_u8 *d = (uae_u8*)lpvBits + (height - y - 1) * dpitch;
uae_u32 *s = (uae_u32*)((uae_u8*)data + y * pitch);
- for (int x = 0; x < w; x++) {
+ for (int x = 0; x < w && x < width; x++) {
uae_u32 v = *s++;
d[0] = v >> 0;
d[1] = v >> 8;
}
}
if (got)
- D3D11_capture(monid, NULL, NULL, NULL, NULL);
+ D3D11_capture(monid, NULL, NULL, NULL, NULL, renderTarget);
d3dcaptured = true;
} else if (D3D_isenabled(0) == 1) {
int w, h, bits;
HRESULT hr;
D3DLOCKED_RECT l;
- LPDIRECT3DSURFACE9 s = D3D_capture(monid, &w, &h, &bits);
+ LPDIRECT3DSURFACE9 s = D3D_capture(monid, &w, &h, &bits, renderTarget);
if (s) {
hr = s->LockRect(&l, NULL, D3DLOCK_READONLY);
if (SUCCEEDED(hr)) {
- int dpitch = (((w * depth + 31) & ~31) / 8);
- lpvBits = xmalloc(uae_u8, dpitch * h);
+ int dpitch = (((width * depth + 31) & ~31) / 8);
+ lpvBits = xmalloc(uae_u8, dpitch * height);
ZeroMemory(bi, sizeof(bi));
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bi->bmiHeader.biWidth = w;
- bi->bmiHeader.biHeight = h;
+ bi->bmiHeader.biWidth = width;
+ bi->bmiHeader.biHeight = height;
bi->bmiHeader.biPlanes = 1;
bi->bmiHeader.biBitCount = depth;
bi->bmiHeader.biCompression = BI_RGB;
if (lpvBits) {
if (bits == 32) {
- for (int y = 0; y < h; y++) {
- uae_u8 *d = (uae_u8*)lpvBits + (h - y - 1) * dpitch;
+ for (int y = 0; y < h && y < height; y++) {
+ uae_u8 *d = (uae_u8*)lpvBits + (height - y - 1) * dpitch;
uae_u32 *s = (uae_u32*)((uae_u8*)l.pBits + y * l.Pitch);
- for (int x = 0; x < w; x++) {
+ for (int x = 0; x < w && x < width; x++) {
uae_u32 v = *s++;
d[0] = v >> 0;
d[1] = v >> 8;
}
}
} else if (bits == 16 || bits == 15) {
- for (int y = 0; y < h; y++) {
- uae_u8 *d = (uae_u8*)lpvBits + (h - y - 1) * dpitch;
+ for (int y = 0; y < h && y < height; y++) {
+ uae_u8 *d = (uae_u8*)lpvBits + (height - y - 1) * dpitch;
uae_u16 *s = (uae_u16*)((uae_u8*)l.pBits + y * l.Pitch);
- for (int x = 0; x < w; x++) {
+ for (int x = 0; x < w && x < width; x++) {
uae_u16 v = s[x];
uae_u16 v2 = v;
if (bits == 16) {
if (!lpvBits)
goto oops;
}
+ unlockrtg();
screenshot_prepared = TRUE;
return 1;
oops:
screenshot_free ();
+ unlockrtg();
return 0;
}