mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-24 22:37:19 +00:00
[host] dxgi: implement downsampling to arbitrary sizes
This commit is contained in:
parent
30c577beeb
commit
5f613b09d6
@ -9,6 +9,7 @@ add_library(capture_DXGI STATIC
|
|||||||
src/util.c
|
src/util.c
|
||||||
src/com_ref.c
|
src/com_ref.c
|
||||||
|
|
||||||
|
src/pp/downsample.c
|
||||||
src/pp/sdrwhitelevel.c
|
src/pp/sdrwhitelevel.c
|
||||||
src/pp/rgb24.c
|
src/pp/rgb24.c
|
||||||
)
|
)
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include "interface/capture.h"
|
#include "interface/capture.h"
|
||||||
#include "interface/platform.h"
|
#include "interface/platform.h"
|
||||||
#include "downsample_parser.h"
|
|
||||||
#include "common/array.h"
|
#include "common/array.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/windebug.h"
|
#include "common/windebug.h"
|
||||||
@ -32,6 +31,7 @@
|
|||||||
#include "common/KVMFR.h"
|
#include "common/KVMFR.h"
|
||||||
#include "common/vector.h"
|
#include "common/vector.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dxgi.h>
|
#include <dxgi.h>
|
||||||
@ -51,9 +51,17 @@
|
|||||||
#define LOCKED(...) INTERLOCKED_SECTION(this->deviceContextLock, __VA_ARGS__)
|
#define LOCKED(...) INTERLOCKED_SECTION(this->deviceContextLock, __VA_ARGS__)
|
||||||
|
|
||||||
//post processers
|
//post processers
|
||||||
|
extern const DXGIPostProcess DXGIPP_Downsample;
|
||||||
extern const DXGIPostProcess DXGIPP_SDRWhiteLevel;
|
extern const DXGIPostProcess DXGIPP_SDRWhiteLevel;
|
||||||
extern const DXGIPostProcess DXGIPP_RGB24;
|
extern const DXGIPostProcess DXGIPP_RGB24;
|
||||||
|
|
||||||
|
const DXGIPostProcess * postProcessors[] =
|
||||||
|
{
|
||||||
|
&DXGIPP_Downsample,
|
||||||
|
&DXGIPP_SDRWhiteLevel,
|
||||||
|
&DXGIPP_RGB24
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ID3D11Texture2D * src;
|
ID3D11Texture2D * src;
|
||||||
@ -81,6 +89,7 @@ static struct DXGICopyBackend * backends[] = {
|
|||||||
static bool dxgi_deinit(void);
|
static bool dxgi_deinit(void);
|
||||||
static CaptureResult dxgi_releaseFrame(void);
|
static CaptureResult dxgi_releaseFrame(void);
|
||||||
|
|
||||||
|
static void ppEarlyInit(void);
|
||||||
static bool ppInit(const DXGIPostProcess * pp, bool shareable);
|
static bool ppInit(const DXGIPostProcess * pp, bool shareable);
|
||||||
static ID3D11Texture2D * ppRun(Texture * tex, ID3D11Texture2D * src,
|
static ID3D11Texture2D * ppRun(Texture * tex, ID3D11Texture2D * src,
|
||||||
int * width, int * height,
|
int * width, int * height,
|
||||||
@ -119,7 +128,6 @@ static void dxgi_initOptions(void)
|
|||||||
.type = OPTION_TYPE_STRING,
|
.type = OPTION_TYPE_STRING,
|
||||||
.value.x_string = NULL
|
.value.x_string = NULL
|
||||||
},
|
},
|
||||||
DOWNSAMPLE_PARSER("dxgi"),
|
|
||||||
{
|
{
|
||||||
.module = "dxgi",
|
.module = "dxgi",
|
||||||
.name = "maxTextures",
|
.name = "maxTextures",
|
||||||
@ -173,6 +181,7 @@ static void dxgi_initOptions(void)
|
|||||||
};
|
};
|
||||||
|
|
||||||
option_register(options);
|
option_register(options);
|
||||||
|
ppEarlyInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dxgi_create(CaptureGetPointerBuffer getPointerBufferFn, CapturePostPointerBuffer postPointerBufferFn)
|
static bool dxgi_create(CaptureGetPointerBuffer getPointerBufferFn, CapturePostPointerBuffer postPointerBufferFn)
|
||||||
@ -693,14 +702,6 @@ static bool dxgi_init(void)
|
|||||||
|
|
||||||
this->outputWidth = this->width;
|
this->outputWidth = this->width;
|
||||||
this->outputHeight = this->height;
|
this->outputHeight = this->height;
|
||||||
DownsampleRule * rule = downsampleRule_match(this->width, this->height);
|
|
||||||
if (rule)
|
|
||||||
{
|
|
||||||
this->outputWidth = rule->targetX;
|
|
||||||
this->outputHeight = rule->targetY;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_INFO("Request Size : %u x %u", this->outputWidth, this->outputHeight);
|
|
||||||
|
|
||||||
const char * copyBackend = option_get_string("dxgi", "copyBackend");
|
const char * copyBackend = option_get_string("dxgi", "copyBackend");
|
||||||
for (int i = 0; i < ARRAY_LENGTH(backends); ++i)
|
for (int i = 0; i < ARRAY_LENGTH(backends); ++i)
|
||||||
@ -738,6 +739,13 @@ static bool dxgi_init(void)
|
|||||||
if (!initVertexShader())
|
if (!initVertexShader())
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (!ppInit(&DXGIPP_Downsample,
|
||||||
|
this->backend != ©BackendD3D11 && !this->hdr))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to intiailize the downsample post processor");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
// if HDR add the SDRWhiteLevel post processor to correct the output
|
// if HDR add the SDRWhiteLevel post processor to correct the output
|
||||||
if (this->hdr)
|
if (this->hdr)
|
||||||
{
|
{
|
||||||
@ -856,10 +864,10 @@ static void rectToFrameDamageRect(RECT * src, FrameDamageRect * dst)
|
|||||||
{
|
{
|
||||||
*dst = (FrameDamageRect)
|
*dst = (FrameDamageRect)
|
||||||
{
|
{
|
||||||
.x = src->left ,
|
.x = floor((double)src->left * this->scaleX),
|
||||||
.y = src->top ,
|
.y = floor((double)src->top * this->scaleY),
|
||||||
.width = (src->right - src->left),
|
.width = ceil ((double)(src->right - src->left) * this->scaleX),
|
||||||
.height = (src->bottom - src->top)
|
.height = ceil ((double)(src->bottom - src->top) * this->scaleY)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -917,10 +925,12 @@ static void computeFrameDamage(Texture * tex)
|
|||||||
|
|
||||||
*texDamageRect++ = (FrameDamageRect)
|
*texDamageRect++ = (FrameDamageRect)
|
||||||
{
|
{
|
||||||
.x = moveRect->SourcePoint.x,
|
.x = floor((double)moveRect->SourcePoint.x * this->scaleX),
|
||||||
.y = moveRect->SourcePoint.y,
|
.y = floor((double)moveRect->SourcePoint.y * this->scaleY),
|
||||||
.width = moveRect->DestinationRect.right - moveRect->DestinationRect.left,
|
.width = ceil((double)(moveRect->DestinationRect.right -
|
||||||
.height = moveRect->DestinationRect.bottom - moveRect->DestinationRect.top
|
moveRect->DestinationRect.left) * this->scaleX),
|
||||||
|
.height = ceil((double)(moveRect->DestinationRect.bottom -
|
||||||
|
moveRect->DestinationRect.top ) * this->scaleY)
|
||||||
};
|
};
|
||||||
|
|
||||||
rectToFrameDamageRect(&moveRect->DestinationRect, texDamageRect++);
|
rectToFrameDamageRect(&moveRect->DestinationRect, texDamageRect++);
|
||||||
@ -1038,14 +1048,6 @@ static CaptureResult dxgi_capture(void)
|
|||||||
{
|
{
|
||||||
if (copyFrame)
|
if (copyFrame)
|
||||||
{
|
{
|
||||||
if (this->useAcquireLock)
|
|
||||||
{
|
|
||||||
LOCKED({ computeFrameDamage(tex); });
|
|
||||||
}
|
|
||||||
else
|
|
||||||
computeFrameDamage(tex);
|
|
||||||
computeTexDamage(tex);
|
|
||||||
|
|
||||||
// run any postprocessors
|
// run any postprocessors
|
||||||
int width = this->width;
|
int width = this->width;
|
||||||
int height = this->height;
|
int height = this->height;
|
||||||
@ -1114,8 +1116,20 @@ static CaptureResult dxgi_capture(void)
|
|||||||
this->dataHeight = rows;
|
this->dataHeight = rows;
|
||||||
this->pitch = pitch;
|
this->pitch = pitch;
|
||||||
this->stride = pitch / this->bpp;
|
this->stride = pitch / this->bpp;
|
||||||
|
|
||||||
|
this->scaleX = (double)width / this->width;
|
||||||
|
this->scaleY = (double)height / this->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute the frame damage
|
||||||
|
if (this->useAcquireLock)
|
||||||
|
{
|
||||||
|
LOCKED({ computeFrameDamage(tex); });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
computeFrameDamage(tex);
|
||||||
|
computeTexDamage(tex);
|
||||||
|
|
||||||
if (!this->backend->copyFrame(tex, dst))
|
if (!this->backend->copyFrame(tex, dst))
|
||||||
{
|
{
|
||||||
result = CAPTURE_RESULT_ERROR;
|
result = CAPTURE_RESULT_ERROR;
|
||||||
@ -1380,6 +1394,13 @@ static CaptureResult dxgi_releaseFrame(void)
|
|||||||
return CAPTURE_RESULT_OK;
|
return CAPTURE_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ppEarlyInit(void)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < ARRAY_LENGTH(postProcessors); ++i)
|
||||||
|
if (postProcessors[i]->earlyInit)
|
||||||
|
postProcessors[i]->earlyInit();
|
||||||
|
}
|
||||||
|
|
||||||
static bool ppInit(const DXGIPostProcess * pp, bool shareable)
|
static bool ppInit(const DXGIPostProcess * pp, bool shareable)
|
||||||
{
|
{
|
||||||
if (!pp->setup(this->device, this->deviceContext, this->output, shareable))
|
if (!pp->setup(this->device, this->deviceContext, this->output, shareable))
|
||||||
@ -1448,7 +1469,7 @@ static ID3D11Texture2D * ppRun(Texture * tex, ID3D11Texture2D * src,
|
|||||||
format))
|
format))
|
||||||
{
|
{
|
||||||
LG_UNLOCK(this->deviceContextLock);
|
LG_UNLOCK(this->deviceContextLock);
|
||||||
DEBUG_ERROR("setFormat failed on a post processor");
|
DEBUG_ERROR("setFormat failed on a post processor (%s)", inst->pp->name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1476,15 +1497,8 @@ static ID3D11Texture2D * ppRun(Texture * tex, ID3D11Texture2D * src,
|
|||||||
// run the post processor
|
// run the post processor
|
||||||
ID3D11Texture2D * out = inst->pp->run(inst->opaque, inst->srv);
|
ID3D11Texture2D * out = inst->pp->run(inst->opaque, inst->srv);
|
||||||
|
|
||||||
// if the post processor failed
|
// if the post processor does nothing, just continue
|
||||||
if (!out)
|
if (!out)
|
||||||
{
|
|
||||||
LG_UNLOCK(this->deviceContextLock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the post processor did nothing, just continue
|
|
||||||
if (out == src)
|
|
||||||
{
|
{
|
||||||
LG_UNLOCK(this->deviceContextLock);
|
LG_UNLOCK(this->deviceContextLock);
|
||||||
continue;
|
continue;
|
||||||
@ -1495,6 +1509,11 @@ static ID3D11Texture2D * ppRun(Texture * tex, ID3D11Texture2D * src,
|
|||||||
*this->deviceContext, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
*this->deviceContext, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
ID3D11DeviceContext_Draw(*this->deviceContext, 4, 0);
|
ID3D11DeviceContext_Draw(*this->deviceContext, 4, 0);
|
||||||
|
|
||||||
|
// unset the target render view
|
||||||
|
static ID3D11RenderTargetView * nullTarget = NULL;
|
||||||
|
ID3D11DeviceContext_OMSetRenderTargets(
|
||||||
|
*this->deviceContext, 1, &nullTarget, NULL);
|
||||||
|
|
||||||
// the output is now the input
|
// the output is now the input
|
||||||
src = out;
|
src = out;
|
||||||
LG_UNLOCK(this->deviceContextLock);
|
LG_UNLOCK(this->deviceContextLock);
|
||||||
|
@ -48,7 +48,7 @@ typedef struct Texture
|
|||||||
uint64_t copyTime;
|
uint64_t copyTime;
|
||||||
uint32_t damageRectsCount;
|
uint32_t damageRectsCount;
|
||||||
FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS];
|
FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS];
|
||||||
int32_t texDamageCount;
|
int texDamageCount;
|
||||||
FrameDamageRect texDamageRects[KVMFR_MAX_DAMAGE_RECTS];
|
FrameDamageRect texDamageRects[KVMFR_MAX_DAMAGE_RECTS];
|
||||||
|
|
||||||
// post processing
|
// post processing
|
||||||
@ -109,6 +109,7 @@ struct DXGIInterface
|
|||||||
unsigned int stride;
|
unsigned int stride;
|
||||||
unsigned int padding;
|
unsigned int padding;
|
||||||
unsigned int bpp;
|
unsigned int bpp;
|
||||||
|
double scaleX, scaleY;
|
||||||
CaptureFormat format, outputFormat;
|
CaptureFormat format, outputFormat;
|
||||||
CaptureRotation rotation;
|
CaptureRotation rotation;
|
||||||
|
|
||||||
|
271
host/platform/Windows/capture/DXGI/src/pp/downsample.c
Normal file
271
host/platform/Windows/capture/DXGI/src/pp/downsample.c
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
/**
|
||||||
|
* Looking Glass
|
||||||
|
* Copyright © 2017-2023 The Looking Glass Authors
|
||||||
|
* https://looking-glass.io
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pp.h"
|
||||||
|
#include "com_ref.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#include "downsample_parser.h"
|
||||||
|
|
||||||
|
#include "common/debug.h"
|
||||||
|
#include "common/windebug.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
typedef struct Downsample
|
||||||
|
{
|
||||||
|
ID3D11Device ** device;
|
||||||
|
ID3D11DeviceContext ** context;
|
||||||
|
bool shareable;
|
||||||
|
|
||||||
|
bool disabled;
|
||||||
|
int width , height;
|
||||||
|
ID3D11SamplerState ** sampler;
|
||||||
|
ID3D11PixelShader ** pshader;
|
||||||
|
}
|
||||||
|
Downsample;
|
||||||
|
static Downsample this = {0};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ID3D11Texture2D ** tex;
|
||||||
|
ID3D11RenderTargetView ** target;
|
||||||
|
}
|
||||||
|
DownsampleInst;
|
||||||
|
|
||||||
|
|
||||||
|
static void downsample_earlyInit(void)
|
||||||
|
{
|
||||||
|
struct Option options[] =
|
||||||
|
{
|
||||||
|
DOWNSAMPLE_PARSER("dxgi"),
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
option_register(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool downsample_setup(
|
||||||
|
ID3D11Device ** device,
|
||||||
|
ID3D11DeviceContext ** context,
|
||||||
|
IDXGIOutput ** output,
|
||||||
|
bool shareable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this.device = device;
|
||||||
|
this.context = context;
|
||||||
|
this.shareable = shareable;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void downsample_finish(void)
|
||||||
|
{
|
||||||
|
memset(&this, 0, sizeof(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool downsample_configure(void * opaque,
|
||||||
|
int * width, int * height,
|
||||||
|
int * cols , int * rows ,
|
||||||
|
CaptureFormat * format)
|
||||||
|
{
|
||||||
|
DownsampleInst * inst = (DownsampleInst *)opaque;
|
||||||
|
if (*format == CAPTURE_FMT_BGR)
|
||||||
|
this.disabled = true;
|
||||||
|
|
||||||
|
if (this.disabled)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
HRESULT status;
|
||||||
|
comRef_scopePush();
|
||||||
|
|
||||||
|
if (!this.pshader)
|
||||||
|
{
|
||||||
|
DownsampleRule * rule = downsampleRule_match(*width, *height);
|
||||||
|
if (!rule || (rule->targetX == *width && rule->targetY == *height))
|
||||||
|
{
|
||||||
|
this.disabled = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.width = rule->targetX;
|
||||||
|
this.height = rule->targetY;
|
||||||
|
|
||||||
|
DEBUG_INFO("Downsampling to: %u x %u", this.width, this.height);
|
||||||
|
|
||||||
|
static const char * pshaderSrc =
|
||||||
|
"Texture2D gInputTexture : register(t0);\n"
|
||||||
|
"SamplerState gSamplerState : register(s0);\n"
|
||||||
|
"\n"
|
||||||
|
"float4 main(\n"
|
||||||
|
" float4 position : SV_POSITION,\n"
|
||||||
|
" float2 texCoord : TEXCOORD0) : SV_TARGET"
|
||||||
|
"{\n"
|
||||||
|
" return gInputTexture.Sample(gSamplerState, texCoord);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
comRef_defineLocal(ID3DBlob, byteCode);
|
||||||
|
if (!compileShader(byteCode, "main", "ps_5_0", pshaderSrc, NULL))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
comRef_defineLocal(ID3D11PixelShader, pshader);
|
||||||
|
HRESULT status = ID3D11Device_CreatePixelShader(
|
||||||
|
*this.device,
|
||||||
|
ID3D10Blob_GetBufferPointer(*byteCode),
|
||||||
|
ID3D10Blob_GetBufferSize (*byteCode),
|
||||||
|
NULL,
|
||||||
|
pshader);
|
||||||
|
|
||||||
|
if (FAILED(status))
|
||||||
|
{
|
||||||
|
DEBUG_WINERROR("Failed to create the pixel shader", status);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
const D3D11_SAMPLER_DESC samplerDesc =
|
||||||
|
{
|
||||||
|
.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR,
|
||||||
|
.AddressU = D3D11_TEXTURE_ADDRESS_WRAP,
|
||||||
|
.AddressV = D3D11_TEXTURE_ADDRESS_WRAP,
|
||||||
|
.AddressW = D3D11_TEXTURE_ADDRESS_WRAP,
|
||||||
|
.ComparisonFunc = D3D11_COMPARISON_NEVER,
|
||||||
|
.MinLOD = 0,
|
||||||
|
.MaxLOD = D3D11_FLOAT32_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
comRef_defineLocal(ID3D11SamplerState, sampler);
|
||||||
|
status = ID3D11Device_CreateSamplerState(*this.device, &samplerDesc, sampler);
|
||||||
|
|
||||||
|
if (FAILED(status))
|
||||||
|
{
|
||||||
|
DEBUG_WINERROR("Failed to create the sampler state", status);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
comRef_toGlobal(this.pshader, pshader);
|
||||||
|
comRef_toGlobal(this.sampler, sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11_TEXTURE2D_DESC texDesc =
|
||||||
|
{
|
||||||
|
.Width = this.width,
|
||||||
|
.Height = this.height,
|
||||||
|
.MipLevels = 1,
|
||||||
|
.ArraySize = 1,
|
||||||
|
.SampleDesc.Count = 1,
|
||||||
|
.SampleDesc.Quality = 0,
|
||||||
|
.Usage = D3D11_USAGE_DEFAULT,
|
||||||
|
.Format = DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
|
.BindFlags = D3D11_BIND_RENDER_TARGET |
|
||||||
|
D3D11_BIND_SHADER_RESOURCE,
|
||||||
|
.CPUAccessFlags = 0,
|
||||||
|
.MiscFlags = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
// allow texture sharing with other backends
|
||||||
|
if (this.shareable)
|
||||||
|
texDesc.MiscFlags |=
|
||||||
|
D3D11_RESOURCE_MISC_SHARED |
|
||||||
|
D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
|
||||||
|
|
||||||
|
comRef_defineLocal(ID3D11Texture2D, tex);
|
||||||
|
status = ID3D11Device_CreateTexture2D(
|
||||||
|
*this.device, &texDesc, NULL, tex);
|
||||||
|
|
||||||
|
if (FAILED(status))
|
||||||
|
{
|
||||||
|
DEBUG_WINERROR("Failed to create the output texture", status);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
comRef_defineLocal(ID3D11RenderTargetView, target);
|
||||||
|
status = ID3D11Device_CreateRenderTargetView(
|
||||||
|
*this.device, *(ID3D11Resource **)tex, NULL, target);
|
||||||
|
|
||||||
|
if (FAILED(status))
|
||||||
|
{
|
||||||
|
DEBUG_WINERROR("Failed to create the render target view", status);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
*width = *cols = this.width;
|
||||||
|
*height = *rows = this.height;
|
||||||
|
|
||||||
|
comRef_toGlobal(inst->tex , tex );
|
||||||
|
comRef_toGlobal(inst->target , target );
|
||||||
|
|
||||||
|
comRef_scopePop();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
comRef_scopePop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool downsample_init(void ** opaque)
|
||||||
|
{
|
||||||
|
DownsampleInst * inst = (DownsampleInst *)calloc(1, sizeof(*inst));
|
||||||
|
if (!inst)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to allocate memory");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*opaque = inst;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void downsample_free(void * opaque)
|
||||||
|
{
|
||||||
|
DownsampleInst * inst = (DownsampleInst *)opaque;
|
||||||
|
comRef_release(inst->target);
|
||||||
|
comRef_release(inst->tex );
|
||||||
|
free(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ID3D11Texture2D * downsample_run(void * opaque,
|
||||||
|
ID3D11ShaderResourceView * srv)
|
||||||
|
{
|
||||||
|
if (this.disabled)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
DownsampleInst * inst = (DownsampleInst *)opaque;
|
||||||
|
|
||||||
|
// set the pixel shader & resources
|
||||||
|
ID3D11DeviceContext_PSSetShader(*this.context, *this.pshader, NULL, 0);
|
||||||
|
ID3D11DeviceContext_PSSetSamplers (*this.context, 0, 1, this.sampler);
|
||||||
|
ID3D11DeviceContext_PSSetShaderResources(*this.context, 0, 1, &srv);
|
||||||
|
|
||||||
|
// set the render target
|
||||||
|
ID3D11DeviceContext_OMSetRenderTargets(*this.context, 1, inst->target, NULL);
|
||||||
|
|
||||||
|
return *inst->tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
DXGIPostProcess DXGIPP_Downsample =
|
||||||
|
{
|
||||||
|
.name = "Downsample",
|
||||||
|
.earlyInit = downsample_earlyInit,
|
||||||
|
.setup = downsample_setup,
|
||||||
|
.init = downsample_init,
|
||||||
|
.free = downsample_free,
|
||||||
|
.configure = downsample_configure,
|
||||||
|
.run = downsample_run,
|
||||||
|
.finish = downsample_finish
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user