diff options
author | James Ross-Gowan <rossy@jrg.systems> | 2018-02-12 21:08:17 +1100 |
---|---|---|
committer | James Ross-Gowan <rossy@jrg.systems> | 2018-02-13 21:25:15 +1100 |
commit | 1b80e124dbec1c4bb80b8ce4aaeb84ff841f9b6d (patch) | |
tree | 15afbd5e96cd783ee51bc55607d1c17da4fe76fc /video/out/d3d11 | |
parent | 7d2228c6738b8793bc616c9436cdc7a1cf149a79 (diff) |
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.c | 7 | ||||
-rw-r--r-- | video/out/d3d11/ra_d3d11.c | 57 |
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, |