mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-10 00:28:20 +00:00
[host] DXGI: initial implementation of RGB24 support
This commit breaks damage tracking and the dx12 backend and is not in a state where it should be used by the general public.
This commit is contained in:
parent
b3879ff1d7
commit
578d98fd22
@ -28,7 +28,7 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#define KVMFR_MAGIC "KVMFR---"
|
#define KVMFR_MAGIC "KVMFR---"
|
||||||
#define KVMFR_VERSION 19
|
#define KVMFR_VERSION 20
|
||||||
|
|
||||||
#define KVMFR_MAX_DAMAGE_RECTS 64
|
#define KVMFR_MAX_DAMAGE_RECTS 64
|
||||||
|
|
||||||
@ -149,6 +149,8 @@ typedef struct KVMFRFrame
|
|||||||
FrameType type; // the frame data type
|
FrameType type; // the frame data type
|
||||||
uint32_t screenWidth; // the client's screen width
|
uint32_t screenWidth; // the client's screen width
|
||||||
uint32_t screenHeight; // the client's screen height
|
uint32_t screenHeight; // the client's screen height
|
||||||
|
uint32_t dataWidth; // the packed width of the frame data
|
||||||
|
uint32_t dataHeight; // the packed height of the frame data
|
||||||
uint32_t frameWidth; // the frame width
|
uint32_t frameWidth; // the frame width
|
||||||
uint32_t frameHeight; // the frame height
|
uint32_t frameHeight; // the frame height
|
||||||
FrameRotation rotation; // the frame rotation
|
FrameRotation rotation; // the frame rotation
|
||||||
|
@ -55,6 +55,7 @@ typedef enum FrameType
|
|||||||
FRAME_TYPE_RGBA , // RGBA interleaved: R,G,B,A 32bpp
|
FRAME_TYPE_RGBA , // RGBA interleaved: R,G,B,A 32bpp
|
||||||
FRAME_TYPE_RGBA10 , // RGBA interleaved: R,G,B,A 10,10,10,2 bpp
|
FRAME_TYPE_RGBA10 , // RGBA interleaved: R,G,B,A 10,10,10,2 bpp
|
||||||
FRAME_TYPE_RGBA16F , // RGBA interleaved: R,G,B,A 16,16,16,16 bpp float
|
FRAME_TYPE_RGBA16F , // RGBA interleaved: R,G,B,A 16,16,16,16 bpp float
|
||||||
|
FRAME_TYPE_BGR , // BGR interleaved: B,G,R 24bpp
|
||||||
FRAME_TYPE_MAX , // sentinel value
|
FRAME_TYPE_MAX , // sentinel value
|
||||||
}
|
}
|
||||||
FrameType;
|
FrameType;
|
||||||
|
@ -26,5 +26,6 @@ const char * FrameTypeStr[FRAME_TYPE_MAX] =
|
|||||||
"FRAME_TYPE_BGRA",
|
"FRAME_TYPE_BGRA",
|
||||||
"FRAME_TYPE_RGBA",
|
"FRAME_TYPE_RGBA",
|
||||||
"FRAME_TYPE_RGBA10",
|
"FRAME_TYPE_RGBA10",
|
||||||
"FRAME_TYPE_RGBA16F"
|
"FRAME_TYPE_RGBA16F",
|
||||||
|
"FRAME_TYPE_BGR"
|
||||||
};
|
};
|
||||||
|
@ -48,6 +48,7 @@ typedef enum CaptureFormat
|
|||||||
CAPTURE_FMT_RGBA ,
|
CAPTURE_FMT_RGBA ,
|
||||||
CAPTURE_FMT_RGBA10 ,
|
CAPTURE_FMT_RGBA10 ,
|
||||||
CAPTURE_FMT_RGBA16F,
|
CAPTURE_FMT_RGBA16F,
|
||||||
|
CAPTURE_FMT_BGR ,
|
||||||
|
|
||||||
// pointer formats
|
// pointer formats
|
||||||
CAPTURE_FMT_COLOR ,
|
CAPTURE_FMT_COLOR ,
|
||||||
@ -69,18 +70,21 @@ CaptureRotation;
|
|||||||
|
|
||||||
typedef struct CaptureFrame
|
typedef struct CaptureFrame
|
||||||
{
|
{
|
||||||
unsigned int formatVer;
|
unsigned formatVer;
|
||||||
unsigned int screenWidth;
|
unsigned screenWidth; // actual screen width
|
||||||
unsigned int screenHeight;
|
unsigned screenHeight; // actual screen height
|
||||||
unsigned int frameWidth;
|
unsigned dataWidth; // the width of the packed frame data
|
||||||
unsigned int frameHeight;
|
unsigned dataHeight; // the height of the packed frame data
|
||||||
bool truncated;
|
unsigned frameWidth; // width of the frame image
|
||||||
unsigned int pitch;
|
unsigned frameHeight; // height of the frame image
|
||||||
unsigned int stride;
|
unsigned pitch; // total width of one row of data in bytes
|
||||||
CaptureFormat format;
|
unsigned stride; // total width of one row of data in pixels
|
||||||
bool hdr;
|
CaptureFormat format; // the data format of the frame
|
||||||
bool hdrPQ;
|
bool truncated; // true if the frame data is truncated
|
||||||
CaptureRotation rotation;
|
bool hdr; // true if the frame format is HDR
|
||||||
|
bool hdrPQ; // true if the frame format is PQ transformed
|
||||||
|
CaptureRotation rotation; // output rotation of the frame
|
||||||
|
|
||||||
uint32_t damageRectsCount;
|
uint32_t damageRectsCount;
|
||||||
FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS];
|
FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS];
|
||||||
}
|
}
|
||||||
@ -94,9 +98,9 @@ typedef struct CapturePointer
|
|||||||
|
|
||||||
bool shapeUpdate;
|
bool shapeUpdate;
|
||||||
CaptureFormat format;
|
CaptureFormat format;
|
||||||
unsigned int hx, hy;
|
unsigned hx, hy;
|
||||||
unsigned int width, height;
|
unsigned width, height;
|
||||||
unsigned int pitch;
|
unsigned pitch;
|
||||||
}
|
}
|
||||||
CapturePointer;
|
CapturePointer;
|
||||||
|
|
||||||
@ -123,6 +127,6 @@ typedef struct CaptureInterface
|
|||||||
|
|
||||||
CaptureResult (*capture )(void);
|
CaptureResult (*capture )(void);
|
||||||
CaptureResult (*waitFrame )(CaptureFrame * frame, const size_t maxFrameSize);
|
CaptureResult (*waitFrame )(CaptureFrame * frame, const size_t maxFrameSize);
|
||||||
CaptureResult (*getFrame )(FrameBuffer * frame, const unsigned int height, int frameIndex);
|
CaptureResult (*getFrame )(FrameBuffer * frame, int frameIndex);
|
||||||
}
|
}
|
||||||
CaptureInterface;
|
CaptureInterface;
|
||||||
|
@ -10,6 +10,7 @@ add_library(capture_DXGI STATIC
|
|||||||
src/com_ref.c
|
src/com_ref.c
|
||||||
|
|
||||||
src/pp/sdrwhitelevel.c
|
src/pp/sdrwhitelevel.c
|
||||||
|
src/pp/rgb24.c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_definitions("-DCOBJMACROS -DINITGUID")
|
add_definitions("-DCOBJMACROS -DINITGUID")
|
||||||
|
@ -35,9 +35,7 @@ struct D3D11Backend
|
|||||||
|
|
||||||
struct D3D11TexImpl
|
struct D3D11TexImpl
|
||||||
{
|
{
|
||||||
ID3D11Texture2D ** gpu;
|
ID3D11Texture2D ** cpu;
|
||||||
ID3D11Texture2D ** cpu;
|
|
||||||
ID3D11ShaderResourceView ** srv;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TEXIMPL(x) ((struct D3D11TexImpl *)(x).impl)
|
#define TEXIMPL(x) ((struct D3D11TexImpl *)(x).impl)
|
||||||
@ -49,7 +47,6 @@ static void d3d11_free(void);
|
|||||||
|
|
||||||
static bool d3d11_create(struct DXGIInterface * intf)
|
static bool d3d11_create(struct DXGIInterface * intf)
|
||||||
{
|
{
|
||||||
HRESULT status;
|
|
||||||
dxgi = intf;
|
dxgi = intf;
|
||||||
|
|
||||||
DEBUG_ASSERT(!this);
|
DEBUG_ASSERT(!this);
|
||||||
@ -61,32 +58,24 @@ static bool d3d11_create(struct DXGIInterface * intf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->avgMapTime = runningavg_new(10);
|
this->avgMapTime = runningavg_new(10);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC gpuTexDesc =
|
static bool d3d11_configure(unsigned width, unsigned height, DXGI_FORMAT format,
|
||||||
{
|
unsigned * pitch)
|
||||||
.Width = dxgi->width,
|
{
|
||||||
.Height = dxgi->height,
|
HRESULT status;
|
||||||
.MipLevels = dxgi->downsampleLevel + 1,
|
|
||||||
.ArraySize = 1,
|
|
||||||
.SampleDesc.Count = 1,
|
|
||||||
.SampleDesc.Quality = 0,
|
|
||||||
.Usage = D3D11_USAGE_DEFAULT,
|
|
||||||
.Format = dxgi->dxgiFormat,
|
|
||||||
.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
|
|
||||||
.CPUAccessFlags = 0,
|
|
||||||
.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS
|
|
||||||
};
|
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC cpuTexDesc =
|
D3D11_TEXTURE2D_DESC cpuTexDesc =
|
||||||
{
|
{
|
||||||
.Width = dxgi->targetWidth,
|
.Width = width,
|
||||||
.Height = dxgi->targetHeight,
|
.Height = height,
|
||||||
.MipLevels = 1,
|
.MipLevels = 1,
|
||||||
.ArraySize = 1,
|
.ArraySize = 1,
|
||||||
.SampleDesc.Count = 1,
|
.SampleDesc.Count = 1,
|
||||||
.SampleDesc.Quality = 0,
|
.SampleDesc.Quality = 0,
|
||||||
.Usage = D3D11_USAGE_STAGING,
|
.Usage = D3D11_USAGE_STAGING,
|
||||||
.Format = dxgi->dxgiFormat,
|
.Format = format,
|
||||||
.BindFlags = 0,
|
.BindFlags = 0,
|
||||||
.CPUAccessFlags = D3D11_CPU_ACCESS_READ,
|
.CPUAccessFlags = D3D11_CPU_ACCESS_READ,
|
||||||
.MiscFlags = 0
|
.MiscFlags = 0
|
||||||
@ -111,22 +100,6 @@ static bool d3d11_create(struct DXGIInterface * intf)
|
|||||||
DEBUG_WINERROR("Failed to create CPU texture", status);
|
DEBUG_WINERROR("Failed to create CPU texture", status);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dxgi->downsampleLevel)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
status = ID3D11Device_CreateTexture2D(*dxgi->device, &gpuTexDesc, NULL,
|
|
||||||
(ID3D11Texture2D **)comRef_newGlobal(&teximpl->gpu));
|
|
||||||
|
|
||||||
if (FAILED(status))
|
|
||||||
{
|
|
||||||
DEBUG_WINERROR("Failed to create GPU texture", status);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D11Device_CreateShaderResourceView(*dxgi->device,
|
|
||||||
*(ID3D11Resource **)teximpl->gpu, NULL,
|
|
||||||
(ID3D11ShaderResourceView **)comRef_newGlobal(&teximpl->srv));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// map the texture simply to get the pitch and stride
|
// map the texture simply to get the pitch and stride
|
||||||
@ -141,16 +114,13 @@ static bool d3d11_create(struct DXGIInterface * intf)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
dxgi->pitch = mapping.RowPitch;
|
|
||||||
dxgi->stride = mapping.RowPitch / dxgi->bpp;
|
|
||||||
|
|
||||||
ID3D11DeviceContext_Unmap(*dxgi->deviceContext,
|
ID3D11DeviceContext_Unmap(*dxgi->deviceContext,
|
||||||
*(ID3D11Resource **)TEXIMPL(dxgi->texture[0])->cpu, 0);
|
*(ID3D11Resource **)TEXIMPL(dxgi->texture[0])->cpu, 0);
|
||||||
|
|
||||||
|
*pitch = mapping.RowPitch;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
d3d11_free();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,76 +169,12 @@ static void copyFrameFull(Texture * tex, ID3D11Texture2D * src)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copyFrameDownsampled(Texture * tex, ID3D11Texture2D * src)
|
|
||||||
{
|
|
||||||
struct D3D11TexImpl * teximpl = TEXIMPL(*tex);
|
|
||||||
ID3D11Texture2D * dst = *teximpl->gpu;
|
|
||||||
|
|
||||||
if (tex->texDamageCount < 0)
|
|
||||||
ID3D11DeviceContext_ResolveSubresource(*dxgi->deviceContext,
|
|
||||||
(ID3D11Resource *)dst, 0,
|
|
||||||
(ID3D11Resource *)src, 0,
|
|
||||||
dxgi->dxgiFormat);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < tex->texDamageCount; ++i)
|
|
||||||
{
|
|
||||||
FrameDamageRect * rect = tex->texDamageRects + i;
|
|
||||||
D3D11_BOX box =
|
|
||||||
{
|
|
||||||
.left = rect->x << dxgi->downsampleLevel,
|
|
||||||
.top = rect->y << dxgi->downsampleLevel,
|
|
||||||
.front = 0,
|
|
||||||
.back = 1,
|
|
||||||
.right = (rect->x + rect->width ) << dxgi->downsampleLevel,
|
|
||||||
.bottom = (rect->y + rect->height) << dxgi->downsampleLevel,
|
|
||||||
};
|
|
||||||
ID3D11DeviceContext_CopySubresourceRegion(*dxgi->deviceContext,
|
|
||||||
(ID3D11Resource *)dst, 0, box.left, box.top, 0,
|
|
||||||
(ID3D11Resource *)src, 0, &box);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D11DeviceContext_GenerateMips(*dxgi->deviceContext, *teximpl->srv);
|
|
||||||
if (tex->texDamageCount < 0)
|
|
||||||
ID3D11DeviceContext_CopySubresourceRegion(*dxgi->deviceContext,
|
|
||||||
*(ID3D11Resource **)teximpl->cpu, 0, 0, 0, 0,
|
|
||||||
(ID3D11Resource * )dst , dxgi->downsampleLevel, NULL);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < tex->texDamageCount; ++i)
|
|
||||||
{
|
|
||||||
FrameDamageRect * rect = tex->texDamageRects + i;
|
|
||||||
D3D11_BOX box =
|
|
||||||
{
|
|
||||||
.left = rect->x,
|
|
||||||
.top = rect->y,
|
|
||||||
.front = 0,
|
|
||||||
.back = 1,
|
|
||||||
.right = rect->x + rect->width ,
|
|
||||||
.bottom = rect->y + rect->height,
|
|
||||||
};
|
|
||||||
|
|
||||||
ID3D11DeviceContext_CopySubresourceRegion(*dxgi->deviceContext,
|
|
||||||
*(ID3D11Resource **)teximpl->cpu, 0, box.left, box.top, 0,
|
|
||||||
(ID3D11Resource * )dst , dxgi->downsampleLevel, &box);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool d3d11_copyFrame(Texture * tex, ID3D11Texture2D * src)
|
static bool d3d11_copyFrame(Texture * tex, ID3D11Texture2D * src)
|
||||||
{
|
{
|
||||||
struct D3D11TexImpl * teximpl = TEXIMPL(*tex);
|
|
||||||
|
|
||||||
INTERLOCKED_SECTION(dxgi->deviceContextLock,
|
INTERLOCKED_SECTION(dxgi->deviceContextLock,
|
||||||
{
|
{
|
||||||
tex->copyTime = microtime();
|
tex->copyTime = microtime();
|
||||||
|
copyFrameFull(tex, src);
|
||||||
if (teximpl->gpu && *teximpl->gpu)
|
|
||||||
copyFrameDownsampled(tex, src);
|
|
||||||
else
|
|
||||||
copyFrameFull(tex, src);
|
|
||||||
|
|
||||||
ID3D11DeviceContext_Flush(*dxgi->deviceContext);
|
ID3D11DeviceContext_Flush(*dxgi->deviceContext);
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
@ -339,6 +245,7 @@ struct DXGICopyBackend copyBackendD3D11 = {
|
|||||||
.name = "Direct3D 11",
|
.name = "Direct3D 11",
|
||||||
.code = "d3d11",
|
.code = "d3d11",
|
||||||
.create = d3d11_create,
|
.create = d3d11_create,
|
||||||
|
.configure = d3d11_configure,
|
||||||
.free = d3d11_free,
|
.free = d3d11_free,
|
||||||
.copyFrame = d3d11_copyFrame,
|
.copyFrame = d3d11_copyFrame,
|
||||||
.mapTexture = d3d11_mapTexture,
|
.mapTexture = d3d11_mapTexture,
|
||||||
|
@ -95,8 +95,8 @@ static bool d3d12_create(struct DXGIInterface * intf)
|
|||||||
{
|
{
|
||||||
DEBUG_WARN("The D3D12 backend does not support downsampling yet");
|
DEBUG_WARN("The D3D12 backend does not support downsampling yet");
|
||||||
dxgi->downsampleLevel = 0;
|
dxgi->downsampleLevel = 0;
|
||||||
dxgi->targetWidth = dxgi->width;
|
dxgi->outputWidth = dxgi->width;
|
||||||
dxgi->targetHeight = dxgi->height;
|
dxgi->outputHeight = dxgi->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dxgi->debug)
|
if (dxgi->debug)
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
|
|
||||||
//post processers
|
//post processers
|
||||||
extern const DXGIPostProcess DXGIPP_SDRWhiteLevel;
|
extern const DXGIPostProcess DXGIPP_SDRWhiteLevel;
|
||||||
|
extern const DXGIPostProcess DXGIPP_RGB24;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -58,6 +59,9 @@ typedef struct
|
|||||||
ID3D11ShaderResourceView * srv;
|
ID3D11ShaderResourceView * srv;
|
||||||
const DXGIPostProcess * pp;
|
const DXGIPostProcess * pp;
|
||||||
void * opaque;
|
void * opaque;
|
||||||
|
|
||||||
|
bool configured;
|
||||||
|
int rows, cols;
|
||||||
}
|
}
|
||||||
PostProcessInstance;
|
PostProcessInstance;
|
||||||
|
|
||||||
@ -89,7 +93,10 @@ static bool dxgi_deinit(void);
|
|||||||
static CaptureResult dxgi_releaseFrame(void);
|
static CaptureResult dxgi_releaseFrame(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 * rows , int * cols,
|
||||||
|
CaptureFormat * format);
|
||||||
static void ppFreeAll(void);
|
static void ppFreeAll(void);
|
||||||
|
|
||||||
// implementation
|
// implementation
|
||||||
@ -301,7 +308,7 @@ static bool initVertexShader(void)
|
|||||||
|
|
||||||
// compile and create the vertex shader
|
// compile and create the vertex shader
|
||||||
comRef_defineLocal(ID3DBlob, byteCode);
|
comRef_defineLocal(ID3DBlob, byteCode);
|
||||||
if (!compileShader(byteCode, "main", "vs_5_0", vshaderSrc))
|
if (!compileShader(byteCode, "main", "vs_5_0", vshaderSrc, NULL))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
comRef_defineLocal(ID3D11VertexShader, vshader);
|
comRef_defineLocal(ID3D11VertexShader, vshader);
|
||||||
@ -530,7 +537,8 @@ static bool dxgi_init(void)
|
|||||||
*tmp,
|
*tmp,
|
||||||
D3D_DRIVER_TYPE_UNKNOWN,
|
D3D_DRIVER_TYPE_UNKNOWN,
|
||||||
NULL,
|
NULL,
|
||||||
D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
|
D3D11_CREATE_DEVICE_VIDEO_SUPPORT |
|
||||||
|
(this->debug ? D3D11_CREATE_DEVICE_DEBUG : 0),
|
||||||
featureLevels, featureLevelCount,
|
featureLevels, featureLevelCount,
|
||||||
D3D11_SDK_VERSION,
|
D3D11_SDK_VERSION,
|
||||||
(ID3D11Device **)comRef_newGlobal(&this->device),
|
(ID3D11Device **)comRef_newGlobal(&this->device),
|
||||||
@ -729,7 +737,7 @@ static bool dxgi_init(void)
|
|||||||
this->hdr = this->dxgiColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
|
this->hdr = this->dxgiColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->bpp = 4;
|
// set the initial format
|
||||||
switch(this->dxgiFormat)
|
switch(this->dxgiFormat)
|
||||||
{
|
{
|
||||||
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
||||||
@ -740,10 +748,12 @@ static bool dxgi_init(void)
|
|||||||
this->format = CAPTURE_FMT_RGBA;
|
this->format = CAPTURE_FMT_RGBA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// we convert to HDR10 to save bandwidth
|
case DXGI_FORMAT_R10G10B10A2_UNORM:
|
||||||
|
this->format = CAPTURE_FMT_RGBA10;
|
||||||
|
break;
|
||||||
|
|
||||||
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
||||||
this->dxgiFormat = DXGI_FORMAT_R10G10B10A2_UNORM;
|
this->format = CAPTURE_FMT_RGBA16F;
|
||||||
this->format = CAPTURE_FMT_RGBA10;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -752,8 +762,8 @@ static bool dxgi_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->downsampleLevel = 0;
|
this->downsampleLevel = 0;
|
||||||
this->targetWidth = this->width;
|
this->outputWidth = this->width;
|
||||||
this->targetHeight = this->height;
|
this->outputHeight = this->height;
|
||||||
|
|
||||||
DownsampleRule * rule, * match = NULL;
|
DownsampleRule * rule, * match = NULL;
|
||||||
vector_forEachRef(rule, &downsampleRules)
|
vector_forEachRef(rule, &downsampleRules)
|
||||||
@ -770,11 +780,11 @@ static bool dxgi_init(void)
|
|||||||
{
|
{
|
||||||
DEBUG_INFO("Matched downsample rule %d", rule->id);
|
DEBUG_INFO("Matched downsample rule %d", rule->id);
|
||||||
this->downsampleLevel = match->level;
|
this->downsampleLevel = match->level;
|
||||||
this->targetWidth >>= match->level;
|
this->outputWidth >>= match->level;
|
||||||
this->targetHeight >>= match->level;
|
this->outputHeight >>= match->level;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_INFO("Request Size : %u x %u", this->targetWidth, this->targetHeight);
|
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)
|
||||||
@ -792,7 +802,7 @@ static bool dxgi_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_INFO("Output Size : %u x %u", this->targetWidth, this->targetHeight);
|
DEBUG_INFO("Output Size : %u x %u", this->outputWidth, this->outputHeight);
|
||||||
|
|
||||||
if (!this->backend)
|
if (!this->backend)
|
||||||
{
|
{
|
||||||
@ -812,23 +822,21 @@ static bool dxgi_init(void)
|
|||||||
if (!initVertexShader())
|
if (!initVertexShader())
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
const D3D11_VIEWPORT vp =
|
|
||||||
{
|
|
||||||
.TopLeftX = 0.0f,
|
|
||||||
.TopLeftY = 0.0f,
|
|
||||||
.Width = this->width,
|
|
||||||
.Height = this->height,
|
|
||||||
.MinDepth = 0.0f,
|
|
||||||
.MaxDepth = 1.0f,
|
|
||||||
};
|
|
||||||
ID3D11DeviceContext_RSSetViewports(*this->deviceContext, 1, &vp);
|
|
||||||
|
|
||||||
// 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 && !ppInit(&DXGIPP_SDRWhiteLevel,
|
if (this->hdr)
|
||||||
this->backend != ©BackendD3D11))
|
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to initialize the SDRWhiteLevel post processor");
|
if (!ppInit(&DXGIPP_SDRWhiteLevel, this->backend != ©BackendD3D11))
|
||||||
goto fail;
|
{
|
||||||
|
DEBUG_ERROR("Failed to initialize the SDRWhiteLevel post processor");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// only support DX11 for this atm
|
||||||
|
if (this->backend == ©BackendD3D11)
|
||||||
|
if (!ppInit(&DXGIPP_RGB24, false))
|
||||||
|
DEBUG_WARN("Failed to initialize the RGB24 post processor");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < LGMP_Q_FRAME_LEN; ++i)
|
for (int i = 0; i < LGMP_Q_FRAME_LEN; ++i)
|
||||||
@ -874,6 +882,7 @@ static bool dxgi_deinit(void)
|
|||||||
ppFreeAll();
|
ppFreeAll();
|
||||||
if (this->backend)
|
if (this->backend)
|
||||||
{
|
{
|
||||||
|
this->backendConfigured = false;
|
||||||
this->backend->free();
|
this->backend->free();
|
||||||
this->backend = NULL;
|
this->backend = NULL;
|
||||||
}
|
}
|
||||||
@ -1121,9 +1130,75 @@ static CaptureResult dxgi_capture(void)
|
|||||||
computeFrameDamage(tex);
|
computeFrameDamage(tex);
|
||||||
computeTexDamage(tex);
|
computeTexDamage(tex);
|
||||||
|
|
||||||
ID3D11Texture2D * dst = ppRun(tex, *src);
|
// run any postprocessors
|
||||||
if (dst != *src)
|
int width = this->width;
|
||||||
ID3D11DeviceContext_Flush(*this->deviceContext);
|
int height = this->height;
|
||||||
|
int cols = this->width;
|
||||||
|
int rows = this->height;
|
||||||
|
CaptureFormat format = this->format;
|
||||||
|
ID3D11Texture2D *dst = ppRun(
|
||||||
|
tex, *src, &width, &height, &cols, &rows, &format);
|
||||||
|
|
||||||
|
if (!this->backendConfigured)
|
||||||
|
{
|
||||||
|
switch(format)
|
||||||
|
{
|
||||||
|
case CAPTURE_FMT_RGBA:
|
||||||
|
this->bpp = 4;
|
||||||
|
this->dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAPTURE_FMT_BGRA:
|
||||||
|
this->bpp = 4;
|
||||||
|
this->dxgiFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAPTURE_FMT_RGBA10:
|
||||||
|
this->bpp = 4;
|
||||||
|
this->dxgiFormat = DXGI_FORMAT_R10G10B10A2_UNORM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAPTURE_FMT_RGBA16F:
|
||||||
|
this->bpp = 8;
|
||||||
|
this->dxgiFormat = DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAPTURE_FMT_BGR:
|
||||||
|
this->bpp = 4;
|
||||||
|
this->dxgiFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAPTURE_FMT_COLOR :
|
||||||
|
case CAPTURE_FMT_MONO :
|
||||||
|
case CAPTURE_FMT_MASKED:
|
||||||
|
case CAPTURE_FMT_MAX :
|
||||||
|
DEBUG_ERROR("Unsupported input format");
|
||||||
|
result = CAPTURE_RESULT_ERROR;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned pitch = 0;
|
||||||
|
LG_LOCK(this->deviceContextLock);
|
||||||
|
if (!this->backend->configure(cols, rows, this->dxgiFormat, &pitch))
|
||||||
|
{
|
||||||
|
LG_UNLOCK(this->deviceContextLock);
|
||||||
|
DEBUG_ERROR("Failed to configure the copy backend");
|
||||||
|
result = CAPTURE_RESULT_ERROR;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
LG_UNLOCK(this->deviceContextLock);
|
||||||
|
|
||||||
|
DEBUG_ASSERT(pitch && "copy backend did not return the pitch");
|
||||||
|
|
||||||
|
this->backendConfigured = true;
|
||||||
|
this->outputWidth = width;
|
||||||
|
this->outputHeight = height;
|
||||||
|
this->outputFormat = format;
|
||||||
|
this->dataWidth = cols;
|
||||||
|
this->dataHeight = rows;
|
||||||
|
this->pitch = pitch;
|
||||||
|
this->stride = pitch / this->bpp;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this->backend->copyFrame(tex, dst))
|
if (!this->backend->copyFrame(tex, dst))
|
||||||
{
|
{
|
||||||
@ -1265,17 +1340,19 @@ static CaptureResult dxgi_waitFrame(CaptureFrame * frame, const size_t maxFrameS
|
|||||||
|
|
||||||
tex->state = TEXTURE_STATE_MAPPED;
|
tex->state = TEXTURE_STATE_MAPPED;
|
||||||
|
|
||||||
const unsigned int maxHeight = maxFrameSize / this->pitch;
|
const unsigned int maxRows = maxFrameSize / this->pitch;
|
||||||
|
|
||||||
frame->formatVer = tex->formatVer;
|
frame->formatVer = tex->formatVer;
|
||||||
frame->screenWidth = this->width;
|
frame->screenWidth = this->width;
|
||||||
frame->screenHeight = this->height;
|
frame->screenHeight = this->height;
|
||||||
frame->frameWidth = this->targetWidth;
|
frame->dataWidth = this->dataWidth;
|
||||||
frame->frameHeight = min(maxHeight, this->targetHeight);
|
frame->dataHeight = min(maxRows, this->dataHeight);
|
||||||
frame->truncated = maxHeight < this->targetHeight;
|
frame->frameWidth = this->outputWidth;
|
||||||
|
frame->frameHeight = this->outputHeight;
|
||||||
|
frame->truncated = maxRows < this->dataHeight;
|
||||||
frame->pitch = this->pitch;
|
frame->pitch = this->pitch;
|
||||||
frame->stride = this->stride;
|
frame->stride = this->stride;
|
||||||
frame->format = this->format;
|
frame->format = this->outputFormat;
|
||||||
frame->hdr = this->hdr;
|
frame->hdr = this->hdr;
|
||||||
frame->hdrPQ = false;
|
frame->hdrPQ = false;
|
||||||
frame->rotation = this->rotation;
|
frame->rotation = this->rotation;
|
||||||
@ -1288,8 +1365,7 @@ static CaptureResult dxgi_waitFrame(CaptureFrame * frame, const size_t maxFrameS
|
|||||||
return CAPTURE_RESULT_OK;
|
return CAPTURE_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CaptureResult dxgi_getFrame(FrameBuffer * frame,
|
static CaptureResult dxgi_getFrame(FrameBuffer * frame, int frameIndex)
|
||||||
const unsigned int height, int frameIndex)
|
|
||||||
{
|
{
|
||||||
DEBUG_ASSERT(this);
|
DEBUG_ASSERT(this);
|
||||||
DEBUG_ASSERT(this->initialized);
|
DEBUG_ASSERT(this->initialized);
|
||||||
@ -1301,14 +1377,14 @@ static CaptureResult dxgi_getFrame(FrameBuffer * frame,
|
|||||||
damage->count + tex->damageRectsCount > KVMFR_MAX_DAMAGE_RECTS;
|
damage->count + tex->damageRectsCount > KVMFR_MAX_DAMAGE_RECTS;
|
||||||
|
|
||||||
if (damageAll)
|
if (damageAll)
|
||||||
framebuffer_write(frame, tex->map, this->pitch * height);
|
framebuffer_write(frame, tex->map, this->pitch * this->dataHeight);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(damage->rects + damage->count, tex->damageRects,
|
memcpy(damage->rects + damage->count, tex->damageRects,
|
||||||
tex->damageRectsCount * sizeof(*tex->damageRects));
|
tex->damageRectsCount * sizeof(*tex->damageRects));
|
||||||
damage->count += tex->damageRectsCount;
|
damage->count += tex->damageRectsCount;
|
||||||
rectsBufferToFramebuffer(damage->rects, damage->count, this->bpp, frame,
|
rectsBufferToFramebuffer(damage->rects, damage->count, this->bpp, frame,
|
||||||
this->pitch, height, tex->map, this->pitch);
|
this->pitch, this->dataHeight, tex->map, this->pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < LGMP_Q_FRAME_LEN; ++i)
|
for (int i = 0; i < LGMP_Q_FRAME_LEN; ++i)
|
||||||
@ -1373,22 +1449,27 @@ static CaptureResult dxgi_releaseFrame(void)
|
|||||||
|
|
||||||
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))
|
if (!pp->setup(this->device, this->deviceContext, this->output, shareable))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for(int i = 0; i < this->maxTextures; ++i)
|
for(int i = 0; i < this->maxTextures; ++i)
|
||||||
{
|
{
|
||||||
PostProcessInstance inst = { .pp = pp };
|
PostProcessInstance inst = { .pp = pp };
|
||||||
if (!pp->init(&inst.opaque, this->width, this->height, shareable))
|
if (!pp->init(&inst.opaque))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to init a post processor");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
vector_push(&this->texture[i].pp, &inst);
|
vector_push(&this->texture[i].pp, &inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ID3D11Texture2D * ppRun(Texture * tex, ID3D11Texture2D * src)
|
static ID3D11Texture2D * ppRun(Texture * tex, ID3D11Texture2D * src,
|
||||||
|
int * width, int * height,
|
||||||
|
int * rows, int * cols,
|
||||||
|
CaptureFormat * format)
|
||||||
{
|
{
|
||||||
PostProcessInstance * inst;
|
PostProcessInstance * inst;
|
||||||
vector_forEachRef(inst, &tex->pp)
|
vector_forEachRef(inst, &tex->pp)
|
||||||
@ -1419,12 +1500,42 @@ static ID3D11Texture2D * ppRun(Texture * tex, ID3D11Texture2D * src)
|
|||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to create the source resource view", status);
|
DEBUG_WINERROR("Failed to create the source resource view", status);
|
||||||
continue;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inst->src = src;
|
inst->src = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LG_LOCK(this->deviceContextLock);
|
||||||
|
if (!inst->configured)
|
||||||
|
{
|
||||||
|
if (!inst->pp->configure(inst->opaque,
|
||||||
|
width, height,
|
||||||
|
cols , rows,
|
||||||
|
format))
|
||||||
|
{
|
||||||
|
LG_UNLOCK(this->deviceContextLock);
|
||||||
|
DEBUG_ERROR("setFormat failed on a post processor");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
inst->configured = true;
|
||||||
|
inst->rows = *rows;
|
||||||
|
inst->cols = *cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the viewport
|
||||||
|
const D3D11_VIEWPORT vp =
|
||||||
|
{
|
||||||
|
.TopLeftX = 0.0f,
|
||||||
|
.TopLeftY = 0.0f,
|
||||||
|
.Width = inst->cols,
|
||||||
|
.Height = inst->rows,
|
||||||
|
.MinDepth = 0.0f,
|
||||||
|
.MaxDepth = 1.0f,
|
||||||
|
};
|
||||||
|
ID3D11DeviceContext_RSSetViewports(*this->deviceContext, 1, &vp);
|
||||||
|
|
||||||
// set the vertex shader
|
// set the vertex shader
|
||||||
ID3D11DeviceContext_VSSetShader(
|
ID3D11DeviceContext_VSSetShader(
|
||||||
*this->deviceContext, *this->vshader, NULL, 0);
|
*this->deviceContext, *this->vshader, NULL, 0);
|
||||||
@ -1432,9 +1543,19 @@ 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 returned a different texture then draw to run it
|
// if the post processor failed
|
||||||
|
if (!out)
|
||||||
|
{
|
||||||
|
LG_UNLOCK(this->deviceContextLock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the post processor did nothing, just continue
|
||||||
if (out == src)
|
if (out == src)
|
||||||
|
{
|
||||||
|
LG_UNLOCK(this->deviceContextLock);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// draw the full screen quad
|
// draw the full screen quad
|
||||||
ID3D11DeviceContext_IASetPrimitiveTopology(
|
ID3D11DeviceContext_IASetPrimitiveTopology(
|
||||||
@ -1443,6 +1564,7 @@ static ID3D11Texture2D * ppRun(Texture * tex, ID3D11Texture2D * src)
|
|||||||
|
|
||||||
// the output is now the input
|
// the output is now the input
|
||||||
src = out;
|
src = out;
|
||||||
|
LG_UNLOCK(this->deviceContextLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return src;
|
return src;
|
||||||
|
@ -96,19 +96,21 @@ struct DXGIInterface
|
|||||||
DXGI_COLOR_SPACE_TYPE dxgiColorSpace;
|
DXGI_COLOR_SPACE_TYPE dxgiColorSpace;
|
||||||
ID3D11VertexShader ** vshader;
|
ID3D11VertexShader ** vshader;
|
||||||
struct DXGICopyBackend * backend;
|
struct DXGICopyBackend * backend;
|
||||||
|
bool backendConfigured;
|
||||||
|
|
||||||
CaptureGetPointerBuffer getPointerBufferFn;
|
CaptureGetPointerBuffer getPointerBufferFn;
|
||||||
CapturePostPointerBuffer postPointerBufferFn;
|
CapturePostPointerBuffer postPointerBufferFn;
|
||||||
LGEvent * frameEvent;
|
LGEvent * frameEvent;
|
||||||
|
|
||||||
unsigned int formatVer;
|
unsigned int formatVer;
|
||||||
unsigned int width , targetWidth ;
|
unsigned int width , outputWidth , dataWidth;
|
||||||
unsigned int height, targetHeight;
|
unsigned int height, outputHeight, dataHeight;
|
||||||
unsigned int downsampleLevel;
|
unsigned int downsampleLevel;
|
||||||
unsigned int pitch;
|
unsigned int pitch;
|
||||||
unsigned int stride;
|
unsigned int stride;
|
||||||
|
unsigned int padding;
|
||||||
unsigned int bpp;
|
unsigned int bpp;
|
||||||
CaptureFormat format;
|
CaptureFormat format, outputFormat;
|
||||||
CaptureRotation rotation;
|
CaptureRotation rotation;
|
||||||
|
|
||||||
int lastPointerX, lastPointerY;
|
int lastPointerX, lastPointerY;
|
||||||
@ -122,6 +124,8 @@ struct DXGICopyBackend
|
|||||||
const char * name;
|
const char * name;
|
||||||
const char * code;
|
const char * code;
|
||||||
bool (*create)(struct DXGIInterface * intf);
|
bool (*create)(struct DXGIInterface * intf);
|
||||||
|
bool (*configure)(unsigned width, unsigned height,
|
||||||
|
DXGI_FORMAT format, unsigned * pitch);
|
||||||
void (*free)(void);
|
void (*free)(void);
|
||||||
bool (*copyFrame)(Texture * tex, ID3D11Texture2D * src);
|
bool (*copyFrame)(Texture * tex, ID3D11Texture2D * src);
|
||||||
CaptureResult (*mapTexture)(Texture * tex);
|
CaptureResult (*mapTexture)(Texture * tex);
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "interface/capture.h"
|
||||||
|
#include "common/locking.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/* the friendly name of the processor for debugging */
|
/* the friendly name of the processor for debugging */
|
||||||
@ -33,14 +36,17 @@ typedef struct
|
|||||||
bool (*setup)(
|
bool (*setup)(
|
||||||
ID3D11Device ** device,
|
ID3D11Device ** device,
|
||||||
ID3D11DeviceContext ** context,
|
ID3D11DeviceContext ** context,
|
||||||
IDXGIOutput ** output);
|
IDXGIOutput ** output,
|
||||||
|
bool shareable);
|
||||||
|
|
||||||
/* instance initialization */
|
/* instance initialization */
|
||||||
bool (*init)(
|
bool (*init)(void ** opaque);
|
||||||
void ** opaque,
|
|
||||||
int width,
|
/* showtime configuration */
|
||||||
int height,
|
bool (*configure)(void * opaque,
|
||||||
bool shareable);
|
int * width, int * height, // the image dimensions
|
||||||
|
int * cols , int * rows , // the texture dimensions for packed data
|
||||||
|
CaptureFormat * type);
|
||||||
|
|
||||||
/* perform the processing */
|
/* perform the processing */
|
||||||
ID3D11Texture2D * (*run)(void * opaque, ID3D11ShaderResourceView * srv);
|
ID3D11Texture2D * (*run)(void * opaque, ID3D11ShaderResourceView * srv);
|
||||||
|
251
host/platform/Windows/capture/DXGI/src/pp/rgb24.c
Normal file
251
host/platform/Windows/capture/DXGI/src/pp/rgb24.c
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
/**
|
||||||
|
* 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 "common/debug.h"
|
||||||
|
#include "common/windebug.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
typedef struct RGB24
|
||||||
|
{
|
||||||
|
ID3D11Device ** device;
|
||||||
|
ID3D11DeviceContext ** context;
|
||||||
|
bool shareable;
|
||||||
|
|
||||||
|
int size;
|
||||||
|
ID3D11PixelShader ** pshader;
|
||||||
|
}
|
||||||
|
RGB24;
|
||||||
|
static RGB24 this = {0};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ID3D11Texture2D ** tex;
|
||||||
|
ID3D11RenderTargetView ** target;
|
||||||
|
}
|
||||||
|
RGB24Inst;
|
||||||
|
|
||||||
|
|
||||||
|
static bool rgb24_setup(
|
||||||
|
ID3D11Device ** device,
|
||||||
|
ID3D11DeviceContext ** context,
|
||||||
|
IDXGIOutput ** output,
|
||||||
|
bool shareable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this.device = device;
|
||||||
|
this.context = context;
|
||||||
|
this.shareable = shareable;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rgb24_finish(void)
|
||||||
|
{
|
||||||
|
memset(&this, 0, sizeof(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool rgb24_configure(void * opaque,
|
||||||
|
int * width, int * height,
|
||||||
|
int * cols , int * rows ,
|
||||||
|
CaptureFormat * format)
|
||||||
|
{
|
||||||
|
RGB24Inst * inst = (RGB24Inst *)opaque;
|
||||||
|
|
||||||
|
HRESULT status;
|
||||||
|
comRef_scopePush();
|
||||||
|
|
||||||
|
if (!this.pshader)
|
||||||
|
{
|
||||||
|
int pixels = (*cols * *rows) * 3 / 4;
|
||||||
|
this.size = (((int)ceil(sqrt(pixels))) + 0x3F) & ~0x3F;
|
||||||
|
|
||||||
|
char sWidth[6], sHeight[6], sSize[6];
|
||||||
|
snprintf(sWidth , sizeof(sWidth ), "%d", *width );
|
||||||
|
snprintf(sHeight, sizeof(sHeight), "%d", *height);
|
||||||
|
snprintf(sSize , sizeof(sSize ), "%d", this.size);
|
||||||
|
|
||||||
|
const D3D_SHADER_MACRO defines[] =
|
||||||
|
{
|
||||||
|
{"INPUT_WIDTH" , sWidth },
|
||||||
|
{"INPUT_HEIGHT" , sHeight},
|
||||||
|
{"OUTPUT_SIZE" , sSize },
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * pshaderSrc =
|
||||||
|
"Texture2D<float4> gInputTexture : register(t0);\n"
|
||||||
|
"\n"
|
||||||
|
"float4 main(\n"
|
||||||
|
" float4 position : SV_POSITION,\n"
|
||||||
|
" float2 texCoord : TEXCOORD0) : SV_TARGET\n"
|
||||||
|
"{\n"
|
||||||
|
" uint outputIdx = uint(texCoord.y * OUTPUT_SIZE) * OUTPUT_SIZE +\n"
|
||||||
|
" uint(texCoord.x * OUTPUT_SIZE);\n"
|
||||||
|
"\n"
|
||||||
|
" uint fst = (outputIdx * 4) / 3;\n"
|
||||||
|
" float4 color0 = gInputTexture.Load(\n"
|
||||||
|
" uint3(fst % INPUT_WIDTH, fst / INPUT_WIDTH, 0));\n"
|
||||||
|
"\n"
|
||||||
|
" uint snd = fst + 1;\n"
|
||||||
|
" float4 color3 = gInputTexture.Load(\n"
|
||||||
|
" uint3(snd % INPUT_WIDTH, snd / INPUT_WIDTH, 0));\n"
|
||||||
|
"\n"
|
||||||
|
" uint outputIdxMod3 = outputIdx % 3;\n"
|
||||||
|
"\n"
|
||||||
|
" float4 color1 = outputIdxMod3 <= 1 ? color0 : color3;\n"
|
||||||
|
" float4 color2 = outputIdxMod3 == 0 ? color0 : color3;\n"
|
||||||
|
"\n"
|
||||||
|
" float b = color0.bgr[outputIdxMod3];\n"
|
||||||
|
" float g = color1.grb[outputIdxMod3];\n"
|
||||||
|
" float r = color2.rbg[outputIdxMod3];\n"
|
||||||
|
" float a = color3.bgr[outputIdxMod3];\n"
|
||||||
|
" return float4(r, g, b, a);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
comRef_defineLocal(ID3DBlob, byteCode);
|
||||||
|
if (!compileShader(byteCode, "main", "ps_5_0", pshaderSrc, defines))
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
comRef_toGlobal(this.pshader, pshader);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This texture is actually going to contain the packed BGR24 output
|
||||||
|
D3D11_TEXTURE2D_DESC texDesc =
|
||||||
|
{
|
||||||
|
.Width = this.size,
|
||||||
|
.Height = this.size,
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
*cols = this.size;
|
||||||
|
*rows = this.size;
|
||||||
|
*format = CAPTURE_FMT_BGR;
|
||||||
|
|
||||||
|
comRef_toGlobal(inst->tex , tex );
|
||||||
|
comRef_toGlobal(inst->target, target );
|
||||||
|
|
||||||
|
comRef_scopePop();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
comRef_scopePop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool rgb24_init(void ** opaque)
|
||||||
|
{
|
||||||
|
RGB24Inst * inst = (RGB24Inst *)calloc(1, sizeof(*inst));
|
||||||
|
if (!inst)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to allocate memory");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*opaque = inst;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rgb24_free(void * opaque)
|
||||||
|
{
|
||||||
|
RGB24Inst * inst = (RGB24Inst *)opaque;
|
||||||
|
comRef_release(inst->target);
|
||||||
|
comRef_release(inst->tex );
|
||||||
|
free(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ID3D11Texture2D * rgb24_run(void * opaque,
|
||||||
|
ID3D11ShaderResourceView * srv)
|
||||||
|
{
|
||||||
|
RGB24Inst * inst = (RGB24Inst *)opaque;
|
||||||
|
|
||||||
|
// set the pixel shader & resources
|
||||||
|
ID3D11DeviceContext_PSSetShader(*this.context, *this.pshader, NULL, 0);
|
||||||
|
ID3D11DeviceContext_PSSetShaderResources(*this.context, 0, 1, &srv);
|
||||||
|
|
||||||
|
// set the render target
|
||||||
|
ID3D11DeviceContext_OMSetRenderTargets(*this.context, 1, inst->target, NULL);
|
||||||
|
|
||||||
|
return *inst->tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
DXGIPostProcess DXGIPP_RGB24 =
|
||||||
|
{
|
||||||
|
.name = "RGB24",
|
||||||
|
.earlyInit = NULL,
|
||||||
|
.setup = rgb24_setup,
|
||||||
|
.init = rgb24_init,
|
||||||
|
.free = rgb24_free,
|
||||||
|
.configure = rgb24_configure,
|
||||||
|
.run = rgb24_run,
|
||||||
|
.finish = rgb24_finish
|
||||||
|
};
|
@ -32,6 +32,7 @@ typedef struct SDRWhiteLevel
|
|||||||
ID3D11Device ** device;
|
ID3D11Device ** device;
|
||||||
ID3D11DeviceContext ** context;
|
ID3D11DeviceContext ** context;
|
||||||
|
|
||||||
|
bool shareable;
|
||||||
ID3D11PixelShader ** pshader;
|
ID3D11PixelShader ** pshader;
|
||||||
ID3D11SamplerState ** sampler;
|
ID3D11SamplerState ** sampler;
|
||||||
ID3D11Buffer ** buffer;
|
ID3D11Buffer ** buffer;
|
||||||
@ -40,7 +41,7 @@ typedef struct SDRWhiteLevel
|
|||||||
float sdrWhiteLevel;
|
float sdrWhiteLevel;
|
||||||
}
|
}
|
||||||
SDRWhiteLevel;
|
SDRWhiteLevel;
|
||||||
SDRWhiteLevel this = {0};
|
static SDRWhiteLevel this = {0};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -60,15 +61,17 @@ static void updateConsts(void);
|
|||||||
static bool sdrWhiteLevel_setup(
|
static bool sdrWhiteLevel_setup(
|
||||||
ID3D11Device ** device,
|
ID3D11Device ** device,
|
||||||
ID3D11DeviceContext ** context,
|
ID3D11DeviceContext ** context,
|
||||||
IDXGIOutput ** output
|
IDXGIOutput ** output,
|
||||||
|
bool shareable
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
comRef_scopePush();
|
comRef_scopePush();
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
|
|
||||||
this.device = device;
|
this.device = device;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
this.shareable = shareable;
|
||||||
|
|
||||||
comRef_defineLocal(IDXGIOutput6, output6);
|
comRef_defineLocal(IDXGIOutput6, output6);
|
||||||
status = IDXGIOutput_QueryInterface(
|
status = IDXGIOutput_QueryInterface(
|
||||||
@ -106,7 +109,7 @@ static bool sdrWhiteLevel_setup(
|
|||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
comRef_defineLocal(ID3DBlob, byteCode);
|
comRef_defineLocal(ID3DBlob, byteCode);
|
||||||
if (!compileShader(byteCode, "main", "ps_5_0", pshaderSrc))
|
if (!compileShader(byteCode, "main", "ps_5_0", pshaderSrc, NULL))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
comRef_defineLocal(ID3D11PixelShader, pshader);
|
comRef_defineLocal(ID3D11PixelShader, pshader);
|
||||||
@ -178,11 +181,7 @@ static void sdrWhiteLevel_finish(void)
|
|||||||
memset(&this, 0, sizeof(this));
|
memset(&this, 0, sizeof(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool sdrWhiteLevel_init(
|
static bool sdrWhiteLevel_init(void ** opaque)
|
||||||
void ** opaque,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
bool shareable)
|
|
||||||
{
|
{
|
||||||
SDRWhiteLevelInst * inst = (SDRWhiteLevelInst *)calloc(1, sizeof(*inst));
|
SDRWhiteLevelInst * inst = (SDRWhiteLevelInst *)calloc(1, sizeof(*inst));
|
||||||
if (!inst)
|
if (!inst)
|
||||||
@ -191,13 +190,48 @@ static bool sdrWhiteLevel_init(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*opaque = inst;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sdrWhiteLevel_free(void * opaque)
|
||||||
|
{
|
||||||
|
SDRWhiteLevelInst * inst = (SDRWhiteLevelInst *)opaque;
|
||||||
|
comRef_release(inst->target);
|
||||||
|
comRef_release(inst->tex );
|
||||||
|
free(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateConsts(void)
|
||||||
|
{
|
||||||
|
float nits = getSDRWhiteLevel(&this.displayPathInfo);
|
||||||
|
if (nits == this.sdrWhiteLevel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.sdrWhiteLevel = nits;
|
||||||
|
|
||||||
|
struct ShaderConsts consts = { .sdrWhiteLevel = 80.0f / nits };
|
||||||
|
ID3D11DeviceContext_UpdateSubresource(
|
||||||
|
*this.context, *(ID3D11Resource**)this.buffer,
|
||||||
|
0, NULL, &consts, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool sdrWhiteLevel_configure(void * opaque,
|
||||||
|
int * width, int * height,
|
||||||
|
int * cols , int * rows,
|
||||||
|
CaptureFormat * format)
|
||||||
|
{
|
||||||
|
SDRWhiteLevelInst * inst = (SDRWhiteLevelInst *)opaque;
|
||||||
|
if (inst->tex)
|
||||||
|
return true;
|
||||||
|
|
||||||
comRef_scopePush();
|
comRef_scopePush();
|
||||||
|
|
||||||
// create the output texture
|
// create the output texture
|
||||||
D3D11_TEXTURE2D_DESC texDesc =
|
D3D11_TEXTURE2D_DESC texDesc =
|
||||||
{
|
{
|
||||||
.Width = width,
|
.Width = *width,
|
||||||
.Height = height,
|
.Height = *height,
|
||||||
.MipLevels = 1,
|
.MipLevels = 1,
|
||||||
.ArraySize = 1,
|
.ArraySize = 1,
|
||||||
.SampleDesc.Count = 1,
|
.SampleDesc.Count = 1,
|
||||||
@ -211,7 +245,7 @@ static bool sdrWhiteLevel_init(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// allow texture sharing with other backends
|
// allow texture sharing with other backends
|
||||||
if (shareable)
|
if (this.shareable)
|
||||||
texDesc.MiscFlags |=
|
texDesc.MiscFlags |=
|
||||||
D3D11_RESOURCE_MISC_SHARED |
|
D3D11_RESOURCE_MISC_SHARED |
|
||||||
D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
|
D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
|
||||||
@ -236,41 +270,19 @@ static bool sdrWhiteLevel_init(
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
*opaque = inst;
|
|
||||||
comRef_toGlobal(inst->tex , tex );
|
comRef_toGlobal(inst->tex , tex );
|
||||||
comRef_toGlobal(inst->target, target);
|
comRef_toGlobal(inst->target, target);
|
||||||
|
|
||||||
comRef_scopePop();
|
comRef_scopePop();
|
||||||
|
|
||||||
|
*format = CAPTURE_FMT_RGBA10;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
comRef_scopePop();
|
comRef_scopePop();
|
||||||
free(inst);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sdrWhiteLevel_free(void * opaque)
|
|
||||||
{
|
|
||||||
SDRWhiteLevelInst * inst = (SDRWhiteLevelInst *)opaque;
|
|
||||||
comRef_release(inst->target);
|
|
||||||
comRef_release(inst->tex );
|
|
||||||
free(inst);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void updateConsts(void)
|
|
||||||
{
|
|
||||||
float nits = getSDRWhiteLevel(&this.displayPathInfo);
|
|
||||||
if (nits == this.sdrWhiteLevel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.sdrWhiteLevel = nits;
|
|
||||||
|
|
||||||
struct ShaderConsts consts = { .sdrWhiteLevel = 80.0f / nits };
|
|
||||||
ID3D11DeviceContext_UpdateSubresource(
|
|
||||||
*this.context, *(ID3D11Resource**)this.buffer,
|
|
||||||
0, NULL, &consts, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ID3D11Texture2D * sdrWhiteLevel_run(void * opaque,
|
static ID3D11Texture2D * sdrWhiteLevel_run(void * opaque,
|
||||||
ID3D11ShaderResourceView * srv)
|
ID3D11ShaderResourceView * srv)
|
||||||
{
|
{
|
||||||
@ -299,6 +311,7 @@ DXGIPostProcess DXGIPP_SDRWhiteLevel =
|
|||||||
.setup = sdrWhiteLevel_setup,
|
.setup = sdrWhiteLevel_setup,
|
||||||
.init = sdrWhiteLevel_init,
|
.init = sdrWhiteLevel_init,
|
||||||
.free = sdrWhiteLevel_free,
|
.free = sdrWhiteLevel_free,
|
||||||
|
.configure = sdrWhiteLevel_configure,
|
||||||
.run = sdrWhiteLevel_run,
|
.run = sdrWhiteLevel_run,
|
||||||
.finish = sdrWhiteLevel_finish
|
.finish = sdrWhiteLevel_finish
|
||||||
};
|
};
|
||||||
|
@ -196,18 +196,18 @@ const char * getDXGIColorSpaceTypeStr(DXGI_COLOR_SPACE_TYPE type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool compileShader(ID3DBlob ** dst, const char * entry, const char * target,
|
bool compileShader(ID3DBlob ** dst, const char * entry, const char * target,
|
||||||
const char * code)
|
const char * code, const D3D_SHADER_MACRO * defines)
|
||||||
{
|
{
|
||||||
ID3DBlob * errors;
|
ID3DBlob * errors;
|
||||||
HRESULT status = D3DCompile(
|
HRESULT status = D3DCompile(
|
||||||
code,
|
code,
|
||||||
strlen(code),
|
strlen(code),
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
defines,
|
||||||
NULL,
|
NULL,
|
||||||
entry,
|
entry,
|
||||||
target,
|
target,
|
||||||
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,
|
0,//D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,
|
||||||
0,
|
0,
|
||||||
dst,
|
dst,
|
||||||
&errors);
|
&errors);
|
||||||
|
@ -25,7 +25,7 @@ const char * getDXGIFormatStr(DXGI_FORMAT format);
|
|||||||
const char * getDXGIColorSpaceTypeStr(DXGI_COLOR_SPACE_TYPE type);
|
const char * getDXGIColorSpaceTypeStr(DXGI_COLOR_SPACE_TYPE type);
|
||||||
|
|
||||||
bool compileShader(ID3DBlob ** dst, const char * entry, const char * target,
|
bool compileShader(ID3DBlob ** dst, const char * entry, const char * target,
|
||||||
const char * code);
|
const char * code, const D3D_SHADER_MACRO * defines);
|
||||||
|
|
||||||
bool getDisplayPathInfo(HMONITOR monitor, DISPLAYCONFIG_PATH_INFO * info);
|
bool getDisplayPathInfo(HMONITOR monitor, DISPLAYCONFIG_PATH_INFO * info);
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ struct iface
|
|||||||
|
|
||||||
unsigned int maxWidth , maxHeight;
|
unsigned int maxWidth , maxHeight;
|
||||||
unsigned int width , height;
|
unsigned int width , height;
|
||||||
|
unsigned int frameHeight;
|
||||||
bool resChanged, scale;
|
bool resChanged, scale;
|
||||||
unsigned int targetWidth, targetHeight;
|
unsigned int targetWidth, targetHeight;
|
||||||
|
|
||||||
@ -744,12 +745,15 @@ static CaptureResult nvfbc_waitFrame(CaptureFrame * frame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const unsigned int maxHeight = maxFrameSize / (this->shmStride * 4);
|
const unsigned int maxHeight = maxFrameSize / (this->shmStride * 4);
|
||||||
|
this->frameHeight = min(maxHeight, this->grabHeight);
|
||||||
|
|
||||||
frame->formatVer = this->formatVer;
|
frame->formatVer = this->formatVer;
|
||||||
frame->screenWidth = this->width;
|
frame->screenWidth = this->width;
|
||||||
frame->screenHeight = this->height;
|
frame->screenHeight = this->height;
|
||||||
|
frame->dataWidth = this->width;
|
||||||
|
frame->dataHeight = this->height;
|
||||||
frame->frameWidth = this->grabWidth;
|
frame->frameWidth = this->grabWidth;
|
||||||
frame->frameHeight = min(maxHeight, this->grabHeight);
|
frame->frameHeight = this->frameHeight;
|
||||||
frame->truncated = maxHeight < this->grabHeight;
|
frame->truncated = maxHeight < this->grabHeight;
|
||||||
frame->pitch = this->shmStride * 4;
|
frame->pitch = this->shmStride * 4;
|
||||||
frame->stride = this->shmStride;
|
frame->stride = this->shmStride;
|
||||||
@ -764,8 +768,7 @@ static CaptureResult nvfbc_waitFrame(CaptureFrame * frame,
|
|||||||
return CAPTURE_RESULT_OK;
|
return CAPTURE_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CaptureResult nvfbc_getFrame(FrameBuffer * frame,
|
static CaptureResult nvfbc_getFrame(FrameBuffer * frame, int frameIndex)
|
||||||
const unsigned int height, int frameIndex)
|
|
||||||
{
|
{
|
||||||
const unsigned int h = DIFF_MAP_DIM(this->grabHeight, this->diffShift);
|
const unsigned int h = DIFF_MAP_DIM(this->grabHeight, this->diffShift);
|
||||||
const unsigned int w = DIFF_MAP_DIM(this->grabWidth, this->diffShift);
|
const unsigned int w = DIFF_MAP_DIM(this->grabWidth, this->diffShift);
|
||||||
@ -779,7 +782,8 @@ static CaptureResult nvfbc_getFrame(FrameBuffer * frame,
|
|||||||
for (unsigned int y = 0; y < h; ++y)
|
for (unsigned int y = 0; y < h; ++y)
|
||||||
{
|
{
|
||||||
const unsigned int ystart = y << this->diffShift;
|
const unsigned int ystart = y << this->diffShift;
|
||||||
const unsigned int yend = min(height, (y + 1) << this->diffShift);
|
const unsigned int yend = min(this->frameHeight, (y + 1)
|
||||||
|
<< this->diffShift);
|
||||||
|
|
||||||
for (unsigned int x = 0; x < w; )
|
for (unsigned int x = 0; x < w; )
|
||||||
{
|
{
|
||||||
@ -804,9 +808,9 @@ static CaptureResult nvfbc_getFrame(FrameBuffer * frame,
|
|||||||
}
|
}
|
||||||
else if (this->grabStride != this->shmStride)
|
else if (this->grabStride != this->shmStride)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < height; y += 64)
|
for (int y = 0; y < this->frameHeight; y += 64)
|
||||||
{
|
{
|
||||||
int yend = min(height, y + 128);
|
int yend = min(this->frameHeight, y + 128);
|
||||||
rectCopyUnaligned(frameData, this->frameBuffer, y, yend, 0, this->shmStride * 4,
|
rectCopyUnaligned(frameData, this->frameBuffer, y, yend, 0, this->shmStride * 4,
|
||||||
this->grabStride * 4, this->grabWidth * 4);
|
this->grabStride * 4, this->grabWidth * 4);
|
||||||
framebuffer_set_write_ptr(frame, yend * this->shmStride * 4);
|
framebuffer_set_write_ptr(frame, yend * this->shmStride * 4);
|
||||||
@ -816,7 +820,7 @@ static CaptureResult nvfbc_getFrame(FrameBuffer * frame,
|
|||||||
framebuffer_write(
|
framebuffer_write(
|
||||||
frame,
|
frame,
|
||||||
this->frameBuffer,
|
this->frameBuffer,
|
||||||
height * this->grabInfo.dwBufferWidth * 4
|
this->frameHeight * this->grabInfo.dwBufferWidth * 4
|
||||||
);
|
);
|
||||||
|
|
||||||
for (int i = 0; i < LGMP_Q_FRAME_LEN; ++i)
|
for (int i = 0; i < LGMP_Q_FRAME_LEN; ++i)
|
||||||
|
@ -250,8 +250,13 @@ static bool sendFrame(void)
|
|||||||
|
|
||||||
switch(frame.format)
|
switch(frame.format)
|
||||||
{
|
{
|
||||||
case CAPTURE_FMT_BGRA : fi->type = FRAME_TYPE_BGRA ; break;
|
case CAPTURE_FMT_BGRA:
|
||||||
case CAPTURE_FMT_RGBA : fi->type = FRAME_TYPE_RGBA ; break;
|
fi->type = FRAME_TYPE_BGRA;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CAPTURE_FMT_RGBA:
|
||||||
|
fi->type = FRAME_TYPE_RGBA;
|
||||||
|
break;
|
||||||
|
|
||||||
case CAPTURE_FMT_RGBA10:
|
case CAPTURE_FMT_RGBA10:
|
||||||
fi->type = FRAME_TYPE_RGBA10;
|
fi->type = FRAME_TYPE_RGBA10;
|
||||||
@ -262,6 +267,10 @@ static bool sendFrame(void)
|
|||||||
flags |= FRAME_FLAG_HDR;
|
flags |= FRAME_FLAG_HDR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CAPTURE_FMT_BGR:
|
||||||
|
fi->type = FRAME_TYPE_BGR;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DEBUG_ERROR("Unsupported frame format %d, skipping frame", frame.format);
|
DEBUG_ERROR("Unsupported frame format %d, skipping frame", frame.format);
|
||||||
return true;
|
return true;
|
||||||
@ -292,6 +301,8 @@ static bool sendFrame(void)
|
|||||||
fi->frameSerial = app.frameSerial++;
|
fi->frameSerial = app.frameSerial++;
|
||||||
fi->screenWidth = frame.screenWidth;
|
fi->screenWidth = frame.screenWidth;
|
||||||
fi->screenHeight = frame.screenHeight;
|
fi->screenHeight = frame.screenHeight;
|
||||||
|
fi->dataWidth = frame.dataWidth;
|
||||||
|
fi->dataHeight = frame.dataHeight;
|
||||||
fi->frameWidth = frame.frameWidth;
|
fi->frameWidth = frame.frameWidth;
|
||||||
fi->frameHeight = frame.frameHeight;
|
fi->frameHeight = frame.frameHeight;
|
||||||
fi->stride = frame.stride;
|
fi->stride = frame.stride;
|
||||||
@ -317,7 +328,7 @@ static bool sendFrame(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
app.iface->getFrame(fb, frame.frameHeight, app.frameIndex);
|
app.iface->getFrame(fb, app.frameIndex);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user