summaryrefslogtreecommitdiffstats
path: root/video/out/d3d11
diff options
context:
space:
mode:
authorJames Ross-Gowan <rossy@jrg.systems>2018-02-12 21:08:17 +1100
committerJames Ross-Gowan <rossy@jrg.systems>2018-02-13 21:25:15 +1100
commit1b80e124dbec1c4bb80b8ce4aaeb84ff841f9b6d (patch)
tree15afbd5e96cd783ee51bc55607d1c17da4fe76fc /video/out/d3d11
parent7d2228c6738b8793bc616c9436cdc7a1cf149a79 (diff)
downloadmpv-1b80e124dbec1c4bb80b8ce4aaeb84ff841f9b6d.tar.bz2
mpv-1b80e124dbec1c4bb80b8ce4aaeb84ff841f9b6d.tar.xz
vo_gpu: d3d11: implement tex_download()
This allows the new GPU screenshot functionality introduced in 9f595f3a80ee to work with the D3D11 backend. It replaces the old window screenshot functionality, which was shared between D3D11 and ANGLE. The old code can be removed, since it's not needed by ANGLE anymore either.
Diffstat (limited to 'video/out/d3d11')
-rw-r--r--video/out/d3d11/context.c7
-rw-r--r--video/out/d3d11/ra_d3d11.c57
2 files changed, 57 insertions, 7 deletions
diff --git a/video/out/d3d11/context.c b/video/out/d3d11/context.c
index af664d9988..82c7d162f7 100644
--- a/video/out/d3d11/context.c
+++ b/video/out/d3d11/context.c
@@ -70,12 +70,6 @@ struct priv {
IDXGISwapChain *swapchain;
};
-static struct mp_image *d3d11_screenshot(struct ra_swapchain *sw)
-{
- struct priv *p = sw->ctx->priv;
- return mp_d3d11_screenshot(p->swapchain);
-}
-
static struct ra_tex *get_backbuffer(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
@@ -179,7 +173,6 @@ static void d3d11_uninit(struct ra_ctx *ctx)
static const struct ra_swapchain_fns d3d11_swapchain = {
.color_depth = d3d11_color_depth,
- .screenshot = d3d11_screenshot,
.start_frame = d3d11_start_frame,
.submit_frame = d3d11_submit_frame,
.swap_buffers = d3d11_swap_buffers,
diff --git a/video/out/d3d11/ra_d3d11.c b/video/out/d3d11/ra_d3d11.c
index bf2657b6f6..1d2455853b 100644
--- a/video/out/d3d11/ra_d3d11.c
+++ b/video/out/d3d11/ra_d3d11.c
@@ -78,6 +78,9 @@ struct d3d_tex {
ID3D11Texture3D *tex3d;
int array_slice;
+ // Staging texture for tex_download(), 2D only
+ ID3D11Texture2D *staging;
+
ID3D11ShaderResourceView *srv;
ID3D11RenderTargetView *rtv;
ID3D11UnorderedAccessView *uav;
@@ -359,12 +362,17 @@ static void tex_destroy(struct ra *ra, struct ra_tex *tex)
SAFE_RELEASE(tex_p->uav);
SAFE_RELEASE(tex_p->sampler);
SAFE_RELEASE(tex_p->res);
+ SAFE_RELEASE(tex_p->staging);
talloc_free(tex);
}
static struct ra_tex *tex_create(struct ra *ra,
const struct ra_tex_params *params)
{
+ // Only 2D textures may be downloaded for now
+ if (params->downloadable && params->dimensions != 2)
+ return NULL;
+
struct ra_d3d11 *p = ra->priv;
HRESULT hr;
@@ -437,6 +445,21 @@ static struct ra_tex *tex_create(struct ra *ra,
goto error;
}
tex_p->res = (ID3D11Resource *)tex_p->tex2d;
+
+ // Create a staging texture with CPU access for tex_download()
+ if (params->downloadable) {
+ desc2d.BindFlags = 0;
+ desc2d.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ desc2d.Usage = D3D11_USAGE_STAGING;
+
+ hr = ID3D11Device_CreateTexture2D(p->dev, &desc2d, NULL,
+ &tex_p->staging);
+ if (FAILED(hr)) {
+ MP_ERR(ra, "Failed to staging texture: %s\n",
+ mp_HRESULT_to_str(hr));
+ goto error;
+ }
+ }
break;
case 3:;
D3D11_TEXTURE3D_DESC desc3d = {
@@ -652,6 +675,39 @@ static bool tex_upload(struct ra *ra, const struct ra_tex_upload_params *params)
return true;
}
+static bool tex_download(struct ra *ra, struct ra_tex_download_params *params)
+{
+ struct ra_d3d11 *p = ra->priv;
+ struct ra_tex *tex = params->tex;
+ struct d3d_tex *tex_p = tex->priv;
+ HRESULT hr;
+
+ if (!tex_p->staging)
+ return false;
+
+ ID3D11DeviceContext_CopyResource(p->ctx, (ID3D11Resource*)tex_p->staging,
+ tex_p->res);
+
+ D3D11_MAPPED_SUBRESOURCE lock;
+ hr = ID3D11DeviceContext_Map(p->ctx, (ID3D11Resource*)tex_p->staging, 0,
+ D3D11_MAP_READ, 0, &lock);
+ if (FAILED(hr)) {
+ MP_ERR(ra, "Failed to map staging texture: %s\n", mp_HRESULT_to_str(hr));
+ return false;
+ }
+
+ char *cdst = params->dst;
+ char *csrc = lock.pData;
+ for (int y = 0; y < tex->params.h; y++) {
+ memcpy(cdst + y * params->stride, csrc + y * lock.RowPitch,
+ MPMIN(params->stride, lock.RowPitch));
+ }
+
+ ID3D11DeviceContext_Unmap(p->ctx, (ID3D11Resource*)tex_p->staging, 0);
+
+ return true;
+}
+
static void buf_destroy(struct ra *ra, struct ra_buf *buf)
{
if (!buf)
@@ -2045,6 +2101,7 @@ static struct ra_fns ra_fns_d3d11 = {
.tex_create = tex_create,
.tex_destroy = tex_destroy,
.tex_upload = tex_upload,
+ .tex_download = tex_download,
.buf_create = buf_create,
.buf_destroy = buf_destroy,
.buf_update = buf_update,