mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-25 23:13:39 +00:00
[host] dxgi: finish downsample support for d3d11 backend
This commit is contained in:
parent
947325e00d
commit
2eec459b47
@ -61,21 +61,11 @@ static bool d3d11_create(struct DXGIInterface * intf)
|
||||
|
||||
this->avgMapTime = runningavg_new(10);
|
||||
|
||||
const bool downsample =
|
||||
dxgi->targetWidth == dxgi->width / 2 &&
|
||||
dxgi->targetHeight == dxgi->height / 2;
|
||||
|
||||
if (!downsample)
|
||||
{
|
||||
dxgi->targetWidth = dxgi->width;
|
||||
dxgi->targetHeight = dxgi->height;
|
||||
}
|
||||
|
||||
D3D11_TEXTURE2D_DESC gpuTexDesc =
|
||||
{
|
||||
.Width = dxgi->width,
|
||||
.Height = dxgi->height,
|
||||
.MipLevels = 2,
|
||||
.MipLevels = dxgi->downsampleLevel + 1,
|
||||
.ArraySize = 1,
|
||||
.SampleDesc.Count = 1,
|
||||
.SampleDesc.Quality = 0,
|
||||
@ -121,7 +111,7 @@ static bool d3d11_create(struct DXGIInterface * intf)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!downsample)
|
||||
if (!dxgi->downsampleLevel)
|
||||
continue;
|
||||
|
||||
status = ID3D11Device_CreateTexture2D(dxgi->device, &gpuTexDesc, NULL,
|
||||
@ -216,15 +206,15 @@ static bool d3d11_copyFrame(Texture * tex, ID3D11Texture2D * src)
|
||||
FrameDamageRect * rect = tex->texDamageRects + i;
|
||||
D3D11_BOX box =
|
||||
{
|
||||
.left = rect->x,
|
||||
.top = rect->y,
|
||||
.left = rect->x << dxgi->downsampleLevel,
|
||||
.top = rect->y << dxgi->downsampleLevel,
|
||||
.front = 0,
|
||||
.back = 1,
|
||||
.right = rect->x + rect->width,
|
||||
.bottom = rect->y + rect->height,
|
||||
.right = (rect->x + rect->width ) << dxgi->downsampleLevel,
|
||||
.bottom = (rect->y + rect->height) << dxgi->downsampleLevel,
|
||||
};
|
||||
ID3D11DeviceContext_CopySubresourceRegion(dxgi->deviceContext,
|
||||
(ID3D11Resource *)dst, 0, rect->x, rect->y, 0,
|
||||
(ID3D11Resource *)dst, 0, box.left, box.top, 0,
|
||||
(ID3D11Resource *)src, 0, &box);
|
||||
}
|
||||
}
|
||||
@ -232,11 +222,10 @@ static bool d3d11_copyFrame(Texture * tex, ID3D11Texture2D * src)
|
||||
if (teximpl->gpu)
|
||||
{
|
||||
ID3D11DeviceContext_GenerateMips(dxgi->deviceContext, teximpl->srv);
|
||||
|
||||
if (tex->texDamageCount < 0)
|
||||
ID3D11DeviceContext_CopySubresourceRegion(dxgi->deviceContext,
|
||||
(ID3D11Resource *)teximpl->cpu, 0, 0, 0, 0,
|
||||
(ID3D11Resource *)dst , 1, NULL);
|
||||
(ID3D11Resource *)dst , dxgi->downsampleLevel, NULL);
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < tex->texDamageCount; ++i)
|
||||
@ -244,17 +233,17 @@ static bool d3d11_copyFrame(Texture * tex, ID3D11Texture2D * src)
|
||||
FrameDamageRect * rect = tex->texDamageRects + i;
|
||||
D3D11_BOX box =
|
||||
{
|
||||
.left = rect->x / 2,
|
||||
.top = rect->y / 2,
|
||||
.left = rect->x,
|
||||
.top = rect->y,
|
||||
.front = 0,
|
||||
.back = 1,
|
||||
.right = (rect->x + rect->width ) / 2,
|
||||
.bottom = (rect->y + rect->height) / 2,
|
||||
.right = rect->x + rect->width ,
|
||||
.bottom = rect->y + rect->height,
|
||||
};
|
||||
|
||||
ID3D11DeviceContext_CopySubresourceRegion(dxgi->deviceContext,
|
||||
(ID3D11Resource *)teximpl->cpu, 0, rect->x / 2, rect->y / 2, 0,
|
||||
(ID3D11Resource *)dst , 1, &box);
|
||||
(ID3D11Resource *)teximpl->cpu, 0, box.left, box.top, 0,
|
||||
(ID3D11Resource *)dst , dxgi->downsampleLevel, &box);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "common/rects.h"
|
||||
#include "common/runningavg.h"
|
||||
#include "common/KVMFR.h"
|
||||
#include "common/vector.h"
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <unistd.h>
|
||||
@ -45,6 +46,18 @@
|
||||
|
||||
#define LOCKED(...) INTERLOCKED_SECTION(this->deviceContextLock, __VA_ARGS__)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int id;
|
||||
bool greater;
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
unsigned int level;
|
||||
}
|
||||
DownsampleRule;
|
||||
|
||||
static Vector downsampleRules = {0};
|
||||
|
||||
// locals
|
||||
static struct DXGIInterface * this = NULL;
|
||||
|
||||
@ -73,6 +86,58 @@ static const char * dxgi_getName(void)
|
||||
return name;
|
||||
}
|
||||
|
||||
static bool downsampleOptParser(struct Option * opt, const char * str)
|
||||
{
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
opt->value.x_string = strdup(str);
|
||||
|
||||
if (downsampleRules.data)
|
||||
vector_destroy(&downsampleRules);
|
||||
|
||||
if (!vector_create(&downsampleRules, sizeof(DownsampleRule), 10))
|
||||
{
|
||||
DEBUG_ERROR("Failed to allocate ram");
|
||||
return false;
|
||||
}
|
||||
|
||||
char * tmp = strdup(str);
|
||||
char * token = strtok(tmp, ",");
|
||||
int count = 0;
|
||||
while(token)
|
||||
{
|
||||
DownsampleRule rule = {0};
|
||||
if (token[0] == '>')
|
||||
{
|
||||
rule.greater = true;
|
||||
++token;
|
||||
}
|
||||
|
||||
if (sscanf(token, "%ux%u:%u", &rule.x, &rule.y, &rule.level) != 3)
|
||||
return false;
|
||||
|
||||
rule.id = count++;
|
||||
|
||||
DEBUG_INFO(
|
||||
"Rule %u: %u%% IF X %s %4u %s Y %s %4u",
|
||||
rule.id,
|
||||
100 / (1 << rule.level),
|
||||
rule.greater ? "> " : "==",
|
||||
rule.x,
|
||||
rule.greater ? "OR " : "AND",
|
||||
rule.greater ? "> " : "==",
|
||||
rule.y
|
||||
);
|
||||
vector_push(&downsampleRules, &rule);
|
||||
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
free(tmp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void dxgi_initOptions(void)
|
||||
{
|
||||
struct Option options[] =
|
||||
@ -91,6 +156,14 @@ static void dxgi_initOptions(void)
|
||||
.type = OPTION_TYPE_STRING,
|
||||
.value.x_string = NULL
|
||||
},
|
||||
{
|
||||
.module = "dxgi",
|
||||
.name = "downsample", //dxgi:downsample=1920x1200:1,
|
||||
.description = "Downsample conditions and levels, format: [>](width)x(height):level",
|
||||
.type = OPTION_TYPE_STRING,
|
||||
.value.x_string = NULL,
|
||||
.parser = downsampleOptParser
|
||||
},
|
||||
{
|
||||
.module = "dxgi",
|
||||
.name = "maxTextures",
|
||||
@ -390,16 +463,6 @@ static bool dxgi_init(void)
|
||||
break;
|
||||
}
|
||||
|
||||
this->targetWidth = this->width;
|
||||
this->targetHeight = this->height;
|
||||
|
||||
//TODO: add logic here
|
||||
if (this->width > 1920 && this->height > 1200)
|
||||
{
|
||||
this->targetWidth /= 2;
|
||||
this->targetHeight /= 2;
|
||||
}
|
||||
|
||||
switch(outputDesc.Rotation)
|
||||
{
|
||||
case DXGI_MODE_ROTATION_ROTATE90:
|
||||
@ -423,7 +486,6 @@ static bool dxgi_init(void)
|
||||
|
||||
DEBUG_INFO("Feature Level : 0x%x" , this->featureLevel);
|
||||
DEBUG_INFO("Capture Size : %u x %u", this->width, this->height);
|
||||
DEBUG_INFO("Target Size : %u x %u", this->targetWidth, this->targetHeight);
|
||||
DEBUG_INFO("AcquireLock : %s" , this->useAcquireLock ? "enabled" : "disabled");
|
||||
DEBUG_INFO("Debug mode : %s" , this->debug ? "enabled" : "disabled");
|
||||
|
||||
@ -536,6 +598,26 @@ static bool dxgi_init(void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
this->targetWidth = this->width;
|
||||
this->targetHeight = this->height;
|
||||
|
||||
DownsampleRule * rule;
|
||||
vector_forEachRef(rule, &downsampleRules)
|
||||
{
|
||||
if (
|
||||
( rule->greater && (this->width > rule->x || this->height > rule->y)) ||
|
||||
(!rule->greater && (this->width == rule->x && this->height == rule->y)))
|
||||
{
|
||||
DEBUG_INFO("Matched downsample rule %d", rule->id);
|
||||
this->downsampleLevel = rule->level;
|
||||
this->targetWidth >>= rule->level;
|
||||
this->targetHeight >>= rule->level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_INFO("Request Size : %u x %u", this->targetWidth, this->targetHeight);
|
||||
|
||||
const char * copyBackend = option_get_string("dxgi", "copyBackend");
|
||||
for (int i = 0; i < ARRAY_LENGTH(backends); ++i)
|
||||
{
|
||||
@ -552,6 +634,8 @@ static bool dxgi_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_INFO("Output Size : %u x %u", this->targetWidth, this->targetHeight);
|
||||
|
||||
if (!this->backend)
|
||||
{
|
||||
DEBUG_ERROR("Could not find copy backend: %s", copyBackend);
|
||||
@ -699,10 +783,10 @@ static void rectToFrameDamageRect(RECT * src, FrameDamageRect * dst)
|
||||
{
|
||||
*dst = (FrameDamageRect)
|
||||
{
|
||||
.x = src->left,
|
||||
.y = src->top,
|
||||
.width = src->right - src->left,
|
||||
.height = src->bottom - src->top
|
||||
.x = src->left >> this->downsampleLevel,
|
||||
.y = src->top >> this->downsampleLevel,
|
||||
.width = (src->right - src->left) >> this->downsampleLevel,
|
||||
.height = (src->bottom - src->top) >> this->downsampleLevel
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,7 @@ struct DXGIInterface
|
||||
unsigned int formatVer;
|
||||
unsigned int width , targetWidth ;
|
||||
unsigned int height, targetHeight;
|
||||
unsigned int downsampleLevel;
|
||||
unsigned int pitch;
|
||||
unsigned int stride;
|
||||
unsigned int bpp;
|
||||
|
Loading…
Reference in New Issue
Block a user