mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 14:57:20 +00:00
[host] dxgi: decouple backends from the DXGI main struct
This commit is contained in:
parent
eb2796d40b
commit
54bd08c3cb
@ -35,23 +35,37 @@ struct DXGICopyBackend
|
|||||||
const char * code;
|
const char * code;
|
||||||
|
|
||||||
// create the copy backend
|
// create the copy backend
|
||||||
bool (*create)(struct DXGIInterface * intf);
|
bool (*create)(unsigned textures);
|
||||||
|
|
||||||
// configure the copy backend with the specified format
|
// configure the copy backend with the specified format
|
||||||
bool (*configure)(unsigned width, unsigned height,
|
bool (*configure)(
|
||||||
DXGI_FORMAT format, unsigned * pitch);
|
unsigned width,
|
||||||
|
unsigned height,
|
||||||
|
DXGI_FORMAT format,
|
||||||
|
unsigned bpp,
|
||||||
|
unsigned * pitch);
|
||||||
|
|
||||||
// free the copy backend
|
// free the copy backend
|
||||||
void (*free)(void);
|
void (*free)(void);
|
||||||
|
|
||||||
// called each captured frame after post processing to copy the frame
|
// called just before the copy starts
|
||||||
bool (*copyFrame)(struct Texture * tex, ID3D11Texture2D * src);
|
bool (*preCopy)(ID3D11Texture2D * src, unsigned textureIndex);
|
||||||
|
|
||||||
|
// called to copy the full frame
|
||||||
|
bool (*copyFull)(ID3D11Texture2D * src, unsigned textureIndex);
|
||||||
|
|
||||||
|
// called for each damage rect that needs to be copied
|
||||||
|
bool (*copyRect)(ID3D11Texture2D * src, unsigned textureIndex,
|
||||||
|
FrameDamageRect * rect);
|
||||||
|
|
||||||
|
// called just after the copy has finished
|
||||||
|
bool (*postCopy)(ID3D11Texture2D * src, unsigned textureIndex);
|
||||||
|
|
||||||
// maps the copied frame into memory
|
// maps the copied frame into memory
|
||||||
CaptureResult (*mapTexture)(struct Texture * tex);
|
CaptureResult (*mapTexture)(unsigned textureIndex, void ** map);
|
||||||
|
|
||||||
// unmaps the copied frame from memory
|
// unmaps the copied frame from memory
|
||||||
void (*unmapTexture)(struct Texture * tex);
|
void (*unmapTexture)(unsigned textureIndex);
|
||||||
|
|
||||||
// called just before the frame is released by the frontend
|
// called just before the frame is released by the frontend
|
||||||
void (*preRelease)(void);
|
void (*preRelease)(void);
|
||||||
|
@ -31,26 +31,29 @@ struct D3D11Backend
|
|||||||
{
|
{
|
||||||
RunningAvg avgMapTime;
|
RunningAvg avgMapTime;
|
||||||
uint64_t usleepMapTime;
|
uint64_t usleepMapTime;
|
||||||
};
|
|
||||||
|
|
||||||
struct D3D11TexImpl
|
unsigned textures;
|
||||||
{
|
struct
|
||||||
|
{
|
||||||
|
uint64_t copyTime;
|
||||||
ID3D11Texture2D ** cpu;
|
ID3D11Texture2D ** cpu;
|
||||||
|
}
|
||||||
|
texture[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TEXIMPL(x) ((struct D3D11TexImpl *)(x).impl)
|
#define TEXIMPL(x) ((struct D3D11TexImpl *)(x).impl)
|
||||||
|
|
||||||
static struct DXGIInterface * dxgi = NULL;
|
|
||||||
static struct D3D11Backend * this = NULL;
|
static struct D3D11Backend * this = NULL;
|
||||||
|
|
||||||
static void d3d11_free(void);
|
static void d3d11_free(void);
|
||||||
|
|
||||||
static bool d3d11_create(struct DXGIInterface * intf)
|
static bool d3d11_create(unsigned textures)
|
||||||
{
|
{
|
||||||
dxgi = intf;
|
|
||||||
|
|
||||||
DEBUG_ASSERT(!this);
|
DEBUG_ASSERT(!this);
|
||||||
this = calloc(1, sizeof(struct D3D11Backend));
|
this = calloc(1,
|
||||||
|
sizeof(struct D3D11Backend) +
|
||||||
|
sizeof(*this->texture) + textures);
|
||||||
|
|
||||||
if (!this)
|
if (!this)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("failed to allocate D3D11Backend struct");
|
DEBUG_ERROR("failed to allocate D3D11Backend struct");
|
||||||
@ -58,10 +61,15 @@ static bool d3d11_create(struct DXGIInterface * intf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->avgMapTime = runningavg_new(10);
|
this->avgMapTime = runningavg_new(10);
|
||||||
|
this->textures = textures;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool d3d11_configure(unsigned width, unsigned height, DXGI_FORMAT format,
|
static bool d3d11_configure(
|
||||||
|
unsigned width,
|
||||||
|
unsigned height,
|
||||||
|
DXGI_FORMAT format,
|
||||||
|
unsigned bpp,
|
||||||
unsigned * pitch)
|
unsigned * pitch)
|
||||||
{
|
{
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
@ -81,32 +89,22 @@ static bool d3d11_configure(unsigned width, unsigned height, DXGI_FORMAT format,
|
|||||||
.MiscFlags = 0
|
.MiscFlags = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < dxgi->maxTextures; ++i)
|
comRef_defineLocal(ID3D11Texture2D, cpu);
|
||||||
|
for(int i = 0; i < this->textures; ++i)
|
||||||
{
|
{
|
||||||
if (!(dxgi->texture[i].impl =
|
status = ID3D11Device_CreateTexture2D(dxgi_getDevice(), &cpuTexDesc, NULL, cpu);
|
||||||
(struct D3D11TexImpl *)calloc(sizeof(struct D3D11TexImpl), 1)))
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to allocate D3D11TexImpl struct");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct D3D11TexImpl * teximpl = TEXIMPL(dxgi->texture[i]);
|
|
||||||
|
|
||||||
status = ID3D11Device_CreateTexture2D(*dxgi->device, &cpuTexDesc, NULL,
|
|
||||||
(ID3D11Texture2D **)comRef_newGlobal(&teximpl->cpu));
|
|
||||||
|
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to create CPU texture", status);
|
DEBUG_WINERROR("Failed to create CPU texture", status);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
comRef_toGlobal(this->texture[i].cpu, cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
// map the texture simply to get the pitch and stride
|
// map the texture simply to get the pitch and stride
|
||||||
D3D11_MAPPED_SUBRESOURCE mapping;
|
D3D11_MAPPED_SUBRESOURCE mapping;
|
||||||
status = ID3D11DeviceContext_Map(*dxgi->deviceContext,
|
status = ID3D11DeviceContext_Map(dxgi_getContext(),
|
||||||
*(ID3D11Resource **)TEXIMPL(dxgi->texture[0])->cpu, 0,
|
*(ID3D11Resource **)this->texture[0].cpu, 0, D3D11_MAP_READ, 0, &mapping);
|
||||||
D3D11_MAP_READ, 0, &mapping);
|
|
||||||
|
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
@ -114,8 +112,8 @@ static bool d3d11_configure(unsigned width, unsigned height, DXGI_FORMAT format,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11DeviceContext_Unmap(*dxgi->deviceContext,
|
ID3D11DeviceContext_Unmap(dxgi_getContext(),
|
||||||
*(ID3D11Resource **)TEXIMPL(dxgi->texture[0])->cpu, 0);
|
*(ID3D11Resource **)this->texture[0].cpu, 0);
|
||||||
|
|
||||||
*pitch = mapping.RowPitch;
|
*pitch = mapping.RowPitch;
|
||||||
return true;
|
return true;
|
||||||
@ -129,35 +127,34 @@ static void d3d11_free(void)
|
|||||||
if (!this)
|
if (!this)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < dxgi->maxTextures; ++i)
|
|
||||||
{
|
|
||||||
struct D3D11TexImpl * teximpl = TEXIMPL(dxgi->texture[i]);
|
|
||||||
free(teximpl);
|
|
||||||
teximpl = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
runningavg_free(&this->avgMapTime);
|
runningavg_free(&this->avgMapTime);
|
||||||
free(this);
|
free(this);
|
||||||
this = NULL;
|
this = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool d3d11_copyFrame(Texture * tex, ID3D11Texture2D * src)
|
static bool d3d11_preCopy(ID3D11Texture2D * src, unsigned textureIndex)
|
||||||
{
|
{
|
||||||
struct D3D11TexImpl * teximpl = TEXIMPL(*tex);
|
dxgi_contextLock();
|
||||||
ID3D11Texture2D * dst = *teximpl->cpu;
|
this->texture[textureIndex].copyTime = microtime();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
INTERLOCKED_SECTION(dxgi->deviceContextLock,
|
static bool d3d11_copyFull(ID3D11Texture2D * src, unsigned textureIndex)
|
||||||
{
|
{
|
||||||
tex->copyTime = microtime();
|
ID3D11Texture2D * dst = *this->texture[textureIndex].cpu;
|
||||||
|
|
||||||
if (tex->texDamageCount < 0)
|
ID3D11DeviceContext_CopyResource(dxgi_getContext(),
|
||||||
ID3D11DeviceContext_CopyResource(*dxgi->deviceContext,
|
|
||||||
(ID3D11Resource *)dst, (ID3D11Resource *)src);
|
(ID3D11Resource *)dst, (ID3D11Resource *)src);
|
||||||
else
|
|
||||||
{
|
return true;
|
||||||
for (int i = 0; i < tex->texDamageCount; ++i)
|
}
|
||||||
{
|
|
||||||
FrameDamageRect * rect = tex->texDamageRects + i;
|
|
||||||
|
static bool d3d11_copyRect(ID3D11Texture2D * src, unsigned textureIndex,
|
||||||
|
FrameDamageRect * rect)
|
||||||
|
{
|
||||||
|
ID3D11Texture2D * dst = *this->texture[textureIndex].cpu;
|
||||||
|
|
||||||
D3D11_BOX box =
|
D3D11_BOX box =
|
||||||
{
|
{
|
||||||
.left = rect->x,
|
.left = rect->x,
|
||||||
@ -168,42 +165,41 @@ static bool d3d11_copyFrame(Texture * tex, ID3D11Texture2D * src)
|
|||||||
.bottom = rect->y + rect->height,
|
.bottom = rect->y + rect->height,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (dxgi->outputFormat == CAPTURE_FMT_BGR)
|
ID3D11DeviceContext_CopySubresourceRegion(
|
||||||
{
|
dxgi_getContext(),
|
||||||
box.left = box.left * 3 / 4;
|
|
||||||
box.right = box.right * 3 / 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D11DeviceContext_CopySubresourceRegion(*dxgi->deviceContext,
|
|
||||||
(ID3D11Resource *)dst, 0, box.left, box.top, 0,
|
(ID3D11Resource *)dst, 0, box.left, box.top, 0,
|
||||||
(ID3D11Resource *)src, 0, &box);
|
(ID3D11Resource *)src, 0, &box);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D11DeviceContext_Flush(*dxgi->deviceContext);
|
|
||||||
});
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CaptureResult d3d11_mapTexture(Texture * tex)
|
static bool d3d11_postCopy(ID3D11Texture2D * src, unsigned textureIndex)
|
||||||
{
|
{
|
||||||
struct D3D11TexImpl * teximpl = TEXIMPL(*tex);
|
ID3D11DeviceContext_Flush(dxgi_getContext());
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
dxgi_contextUnlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CaptureResult d3d11_mapTexture(unsigned textureIndex, void ** map)
|
||||||
|
{
|
||||||
|
ID3D11Resource * cpu = *(ID3D11Resource **)this->texture[textureIndex].cpu;
|
||||||
|
|
||||||
// sleep until it's close to time to map
|
// sleep until it's close to time to map
|
||||||
const uint64_t delta = microtime() - tex->copyTime;
|
const uint64_t delta = microtime() - this->texture[textureIndex].copyTime;
|
||||||
if (delta < this->usleepMapTime)
|
if (delta < this->usleepMapTime)
|
||||||
usleep(this->usleepMapTime - delta);
|
usleep(this->usleepMapTime - delta);
|
||||||
|
|
||||||
|
D3D11_MAPPED_SUBRESOURCE mappedRes;
|
||||||
|
|
||||||
// try to map the resource, but don't wait for it
|
// try to map the resource, but don't wait for it
|
||||||
for (int i = 0; ; ++i)
|
for (int i = 0; ; ++i)
|
||||||
{
|
{
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
|
|
||||||
INTERLOCKED_SECTION(dxgi->deviceContextLock, {
|
dxgi_contextLock();
|
||||||
status = ID3D11DeviceContext_Map(*dxgi->deviceContext,
|
status = ID3D11DeviceContext_Map(dxgi_getContext(), cpu, 0, D3D11_MAP_READ,
|
||||||
(ID3D11Resource *)*teximpl->cpu, 0, D3D11_MAP_READ, 0x100000L, &map);
|
0x100000L, &mappedRes);
|
||||||
});
|
dxgi_contextUnlock();
|
||||||
if (status == DXGI_ERROR_WAS_STILL_DRAWING)
|
if (status == DXGI_ERROR_WAS_STILL_DRAWING)
|
||||||
{
|
{
|
||||||
if (i == 100)
|
if (i == 100)
|
||||||
@ -222,23 +218,23 @@ static CaptureResult d3d11_mapTexture(Texture * tex)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tex->map = map.pData;
|
*map = mappedRes.pData;
|
||||||
|
|
||||||
// update the sleep average and sleep for 80% of the average on the next call
|
// update the sleep average and sleep for 80% of the average on the next call
|
||||||
runningavg_push(this->avgMapTime, microtime() - tex->copyTime);
|
runningavg_push(this->avgMapTime,
|
||||||
|
microtime() - this->texture[textureIndex].copyTime);
|
||||||
|
|
||||||
this->usleepMapTime = (uint64_t)(runningavg_calc(this->avgMapTime) * 0.8);
|
this->usleepMapTime = (uint64_t)(runningavg_calc(this->avgMapTime) * 0.8);
|
||||||
return CAPTURE_RESULT_OK;
|
return CAPTURE_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void d3d11_unmapTexture(Texture * tex)
|
static void d3d11_unmapTexture(unsigned textureIndex)
|
||||||
{
|
{
|
||||||
struct D3D11TexImpl * teximpl = TEXIMPL(*tex);
|
ID3D11Resource * cpu = *(ID3D11Resource **)this->texture[textureIndex].cpu;
|
||||||
|
|
||||||
INTERLOCKED_SECTION(dxgi->deviceContextLock, {
|
dxgi_contextLock();
|
||||||
ID3D11DeviceContext_Unmap(*dxgi->deviceContext,
|
ID3D11DeviceContext_Unmap(dxgi_getContext(), cpu, 0);
|
||||||
(ID3D11Resource *)*teximpl->cpu, 0);
|
dxgi_contextUnlock();
|
||||||
});
|
|
||||||
tex->map = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void d3d11_preRelease(void)
|
static void d3d11_preRelease(void)
|
||||||
@ -252,7 +248,10 @@ struct DXGICopyBackend copyBackendD3D11 = {
|
|||||||
.create = d3d11_create,
|
.create = d3d11_create,
|
||||||
.configure = d3d11_configure,
|
.configure = d3d11_configure,
|
||||||
.free = d3d11_free,
|
.free = d3d11_free,
|
||||||
.copyFrame = d3d11_copyFrame,
|
.preCopy = d3d11_preCopy,
|
||||||
|
.copyFull = d3d11_copyFull,
|
||||||
|
.copyRect = d3d11_copyRect,
|
||||||
|
.postCopy = d3d11_postCopy,
|
||||||
.mapTexture = d3d11_mapTexture,
|
.mapTexture = d3d11_mapTexture,
|
||||||
.unmapTexture = d3d11_unmapTexture,
|
.unmapTexture = d3d11_unmapTexture,
|
||||||
.preRelease = d3d11_preRelease,
|
.preRelease = d3d11_preRelease,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* Looking Glass
|
|
||||||
* Copyright © 2017-2023 The Looking Glass Authors
|
* Copyright © 2017-2023 The Looking Glass Authors
|
||||||
* https://looking-glass.io
|
* https://looking-glass.io
|
||||||
*
|
*
|
||||||
@ -58,7 +57,6 @@ struct D3D12Backend
|
|||||||
float copySleep;
|
float copySleep;
|
||||||
ID3D12Device ** device;
|
ID3D12Device ** device;
|
||||||
ID3D12CommandQueue ** commandQueue;
|
ID3D12CommandQueue ** commandQueue;
|
||||||
struct D3D12Texture * texture;
|
|
||||||
UINT64 fenceValue;
|
UINT64 fenceValue;
|
||||||
ID3D12Fence ** fence;
|
ID3D12Fence ** fence;
|
||||||
HANDLE event;
|
HANDLE event;
|
||||||
@ -66,9 +64,12 @@ struct D3D12Backend
|
|||||||
// shared handle cache
|
// shared handle cache
|
||||||
struct SharedCache sharedCache[10];
|
struct SharedCache sharedCache[10];
|
||||||
int sharedCacheCount;
|
int sharedCacheCount;
|
||||||
|
ID3D12Resource * d12src;
|
||||||
|
|
||||||
|
unsigned textures;
|
||||||
|
struct D3D12Texture texture[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct DXGIInterface * dxgi = NULL;
|
|
||||||
static struct D3D12Backend * this = NULL;
|
static struct D3D12Backend * this = NULL;
|
||||||
|
|
||||||
typedef HRESULT (*D3D12CreateDevice_t)(
|
typedef HRESULT (*D3D12CreateDevice_t)(
|
||||||
@ -85,18 +86,17 @@ typedef HRESULT (*D3D12GetDebugInterface_t)(
|
|||||||
|
|
||||||
static void d3d12_free(void);
|
static void d3d12_free(void);
|
||||||
|
|
||||||
static bool d3d12_create(struct DXGIInterface * intf)
|
static bool d3d12_create(unsigned textures)
|
||||||
{
|
{
|
||||||
DEBUG_ASSERT(!this);
|
DEBUG_ASSERT(!this);
|
||||||
|
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
dxgi = intf;
|
|
||||||
|
|
||||||
HMODULE d3d12 = LoadLibrary("d3d12.dll");
|
HMODULE d3d12 = LoadLibrary("d3d12.dll");
|
||||||
if (!d3d12)
|
if (!d3d12)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (dxgi->debug)
|
if (dxgi_debug())
|
||||||
{
|
{
|
||||||
D3D12GetDebugInterface_t D3D12GetDebugInterface = (D3D12GetDebugInterface_t)
|
D3D12GetDebugInterface_t D3D12GetDebugInterface = (D3D12GetDebugInterface_t)
|
||||||
GetProcAddress(d3d12, "D3D12GetDebugInterface");
|
GetProcAddress(d3d12, "D3D12GetDebugInterface");
|
||||||
@ -118,20 +118,17 @@ static bool d3d12_create(struct DXGIInterface * intf)
|
|||||||
if (!D3D12CreateDevice)
|
if (!D3D12CreateDevice)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
this = calloc(1, sizeof(struct D3D12Backend));
|
this = calloc(1,
|
||||||
|
sizeof(struct D3D12Backend) +
|
||||||
|
sizeof(*this->texture) * textures);
|
||||||
|
|
||||||
if (!this)
|
if (!this)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("failed to allocate D3D12Backend struct");
|
DEBUG_ERROR("failed to allocate D3D12Backend struct");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->texture = calloc(dxgi->maxTextures, sizeof(struct D3D12Texture));
|
this->textures = textures;
|
||||||
if (!this->texture)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to allocate memory");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->copySleep = option_get_float("dxgi", "d3d12CopySleep");
|
this->copySleep = option_get_float("dxgi", "d3d12CopySleep");
|
||||||
DEBUG_INFO("Sleep before copy : %f ms", this->copySleep);
|
DEBUG_INFO("Sleep before copy : %f ms", this->copySleep);
|
||||||
|
|
||||||
@ -139,8 +136,8 @@ static bool d3d12_create(struct DXGIInterface * intf)
|
|||||||
comRef_scopePush();
|
comRef_scopePush();
|
||||||
|
|
||||||
comRef_defineLocal(ID3D12Device, device);
|
comRef_defineLocal(ID3D12Device, device);
|
||||||
status = D3D12CreateDevice(*(IUnknown **)dxgi->adapter, D3D_FEATURE_LEVEL_11_0,
|
status = D3D12CreateDevice((IUnknown *)dxgi_getAdapter(),
|
||||||
&IID_ID3D12Device, (void **)device);
|
D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)device);
|
||||||
|
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
@ -200,7 +197,11 @@ exit:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool d3d12_configure(unsigned width, unsigned height, DXGI_FORMAT format,
|
static bool d3d12_configure(
|
||||||
|
unsigned width,
|
||||||
|
unsigned height,
|
||||||
|
DXGI_FORMAT format,
|
||||||
|
unsigned bpp,
|
||||||
unsigned * pitch)
|
unsigned * pitch)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@ -210,7 +211,7 @@ static bool d3d12_configure(unsigned width, unsigned height, DXGI_FORMAT format,
|
|||||||
this->width = width;
|
this->width = width;
|
||||||
this->height = height;
|
this->height = height;
|
||||||
this->format = format;
|
this->format = format;
|
||||||
this->pitch = ALIGN_TO(width * dxgi->bpp, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
this->pitch = ALIGN_TO(width * bpp, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
|
||||||
|
|
||||||
D3D12_HEAP_PROPERTIES readbackHeapProperties =
|
D3D12_HEAP_PROPERTIES readbackHeapProperties =
|
||||||
{
|
{
|
||||||
@ -237,7 +238,7 @@ static bool d3d12_configure(unsigned width, unsigned height, DXGI_FORMAT format,
|
|||||||
comRef_defineLocal(ID3D12CommandAllocator , commandAllocator );
|
comRef_defineLocal(ID3D12CommandAllocator , commandAllocator );
|
||||||
comRef_defineLocal(ID3D12GraphicsCommandList, graphicsCommandList);
|
comRef_defineLocal(ID3D12GraphicsCommandList, graphicsCommandList);
|
||||||
comRef_defineLocal(ID3D12CommandList , commandList );
|
comRef_defineLocal(ID3D12CommandList , commandList );
|
||||||
for (int i = 0; i < dxgi->maxTextures; ++i)
|
for (int i = 0; i < this->textures; ++i)
|
||||||
{
|
{
|
||||||
status = ID3D12Device_CreateCommittedResource(*this->device,
|
status = ID3D12Device_CreateCommittedResource(*this->device,
|
||||||
&readbackHeapProperties,
|
&readbackHeapProperties,
|
||||||
@ -306,8 +307,6 @@ static bool d3d12_configure(unsigned width, unsigned height, DXGI_FORMAT format,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
dxgi->texture[i].impl = this->texture + i;
|
|
||||||
|
|
||||||
comRef_toGlobal(this->texture[i].tex , texture );
|
comRef_toGlobal(this->texture[i].tex , texture );
|
||||||
comRef_toGlobal(this->texture[i].fence , fence );
|
comRef_toGlobal(this->texture[i].fence , fence );
|
||||||
comRef_toGlobal(this->texture[i].commandAllocator , commandAllocator );
|
comRef_toGlobal(this->texture[i].commandAllocator , commandAllocator );
|
||||||
@ -329,13 +328,9 @@ static void d3d12_free(void)
|
|||||||
if (!this)
|
if (!this)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this->texture)
|
for (int i = 0; i < this->textures; ++i)
|
||||||
{
|
|
||||||
for (int i = 0; i < dxgi->maxTextures; ++i)
|
|
||||||
if (this->texture[i].event)
|
if (this->texture[i].event)
|
||||||
CloseHandle(this->texture[i].event);
|
CloseHandle(this->texture[i].event);
|
||||||
free(this->texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->event)
|
if (this->event)
|
||||||
CloseHandle(this->event);
|
CloseHandle(this->event);
|
||||||
@ -344,42 +339,40 @@ static void d3d12_free(void)
|
|||||||
this = NULL;
|
this = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
static bool d3d12_preCopy(ID3D11Texture2D * src, unsigned textureIndex)
|
||||||
{
|
{
|
||||||
// we need to flush the DX11 context explicity or we get tons of lag
|
|
||||||
ID3D11DeviceContext_Flush(*dxgi->deviceContext);
|
|
||||||
|
|
||||||
comRef_scopePush();
|
comRef_scopePush();
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
struct D3D12Texture * tex = parent->impl;
|
// we need to flush the DX11 context explicity or we get tons of lag
|
||||||
bool fail = true;
|
dxgi_contextLock();
|
||||||
comRef_defineLocal(IDXGIResource1, res1);
|
ID3D11DeviceContext_Flush(dxgi_getContext());
|
||||||
ID3D12Resource * d12src = NULL;
|
dxgi_contextUnlock();
|
||||||
HRESULT status;
|
|
||||||
|
|
||||||
if (this->copySleep > 0)
|
if (this->copySleep > 0)
|
||||||
nsleep((uint64_t)(this->copySleep * 1000000));
|
nsleep((uint64_t)(this->copySleep * 1000000));
|
||||||
|
|
||||||
|
this->d12src = NULL;
|
||||||
if (this->sharedCacheCount > -1)
|
if (this->sharedCacheCount > -1)
|
||||||
{
|
{
|
||||||
// see if there is a cached handle already available for this texture
|
// see if there is a cached handle already available for this texture
|
||||||
for(int i = 0; i < this->sharedCacheCount; ++i)
|
for(int i = 0; i < this->sharedCacheCount; ++i)
|
||||||
if (this->sharedCache[i].tex == src)
|
if (this->sharedCache[i].tex == src)
|
||||||
{
|
{
|
||||||
d12src = *this->sharedCache[i].d12src;
|
this->d12src = *this->sharedCache[i].d12src;
|
||||||
break;
|
result = true;
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!d12src)
|
comRef_defineLocal(IDXGIResource1, res1);
|
||||||
{
|
HRESULT status = ID3D11Texture2D_QueryInterface(src,
|
||||||
status = ID3D11Texture2D_QueryInterface(src,
|
|
||||||
&IID_IDXGIResource1, (void **)res1);
|
&IID_IDXGIResource1, (void **)res1);
|
||||||
|
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to get IDXGIResource1 from texture", status);
|
DEBUG_WINERROR("Failed to get IDXGIResource1 from texture", status);
|
||||||
goto cleanup;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
@ -389,17 +382,18 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to get create shared handle for texture", status);
|
DEBUG_WINERROR("Failed to get create shared handle for texture", status);
|
||||||
goto cleanup;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = ID3D12Device_OpenSharedHandle(*this->device,
|
status = ID3D12Device_OpenSharedHandle(*this->device,
|
||||||
handle, &IID_ID3D12Resource, (void **)&d12src);
|
handle, &IID_ID3D12Resource, (void **)&this->d12src);
|
||||||
|
|
||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
|
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to open the shared handle for texture", status);
|
DEBUG_WINERROR("Failed to open the shared handle for texture", status);
|
||||||
goto cleanup;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the texture for later use
|
// store the texture for later use
|
||||||
@ -407,7 +401,7 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||||||
{
|
{
|
||||||
struct SharedCache *cache = &this->sharedCache[this->sharedCacheCount++];
|
struct SharedCache *cache = &this->sharedCache[this->sharedCacheCount++];
|
||||||
cache->tex = src;
|
cache->tex = src;
|
||||||
*comRef_newGlobal(&cache->d12src) = (IUnknown *)d12src;
|
*comRef_newGlobal(&cache->d12src) = (IUnknown *)this->d12src;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -419,11 +413,23 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||||||
}
|
}
|
||||||
this->sharedCacheCount = -1;
|
this->sharedCacheCount = -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (!result)
|
||||||
|
comRef_scopePop();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool d3d12_copyFull(ID3D11Texture2D * src, unsigned textureIndex)
|
||||||
|
{
|
||||||
|
struct D3D12Texture * tex = &this->texture[textureIndex];
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION srcLoc =
|
D3D12_TEXTURE_COPY_LOCATION srcLoc =
|
||||||
{
|
{
|
||||||
.pResource = d12src,
|
.pResource = this->d12src,
|
||||||
.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||||
.SubresourceIndex = 0
|
.SubresourceIndex = 0
|
||||||
};
|
};
|
||||||
@ -446,16 +452,43 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (parent->texDamageCount < 0)
|
|
||||||
{
|
|
||||||
ID3D12GraphicsCommandList_CopyTextureRegion(*tex->graphicsCommandList,
|
ID3D12GraphicsCommandList_CopyTextureRegion(*tex->graphicsCommandList,
|
||||||
&destLoc, 0, 0, 0, &srcLoc, NULL);
|
&destLoc, 0, 0, 0, &srcLoc, NULL);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool d3d12_copyRect(ID3D11Texture2D * src, unsigned textureIndex,
|
||||||
|
FrameDamageRect * rect)
|
||||||
|
{
|
||||||
|
struct D3D12Texture * tex = &this->texture[textureIndex];
|
||||||
|
|
||||||
|
D3D12_TEXTURE_COPY_LOCATION srcLoc =
|
||||||
|
{
|
||||||
|
.pResource = this->d12src,
|
||||||
|
.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||||
|
.SubresourceIndex = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
D3D12_TEXTURE_COPY_LOCATION destLoc =
|
||||||
|
{
|
||||||
|
.pResource = *tex->tex,
|
||||||
|
.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
||||||
|
.PlacedFootprint =
|
||||||
|
{
|
||||||
|
.Offset = 0,
|
||||||
|
.Footprint =
|
||||||
|
{
|
||||||
|
.Format = this->format,
|
||||||
|
.Width = this->width,
|
||||||
|
.Height = this->height,
|
||||||
|
.Depth = 1,
|
||||||
|
.RowPitch = this->pitch,
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
};
|
||||||
for (int i = 0; i < parent->texDamageCount; ++i)
|
|
||||||
{
|
|
||||||
FrameDamageRect * rect = parent->texDamageRects + i;
|
|
||||||
D3D12_BOX box =
|
D3D12_BOX box =
|
||||||
{
|
{
|
||||||
.left = rect->x,
|
.left = rect->x,
|
||||||
@ -466,22 +499,22 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||||||
.bottom = rect->y + rect->height,
|
.bottom = rect->y + rect->height,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (dxgi->outputFormat == CAPTURE_FMT_BGR)
|
|
||||||
{
|
|
||||||
box.left = box.left * 3 / 4;
|
|
||||||
box.right = box.right * 3 / 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D12GraphicsCommandList_CopyTextureRegion(*tex->graphicsCommandList,
|
ID3D12GraphicsCommandList_CopyTextureRegion(*tex->graphicsCommandList,
|
||||||
&destLoc, box.left, box.top, 0, &srcLoc, &box);
|
&destLoc, box.left, box.top, 0, &srcLoc, &box);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
status = ID3D12GraphicsCommandList_Close(*tex->graphicsCommandList);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool d3d12_postCopy(ID3D11Texture2D * src, unsigned textureIndex)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
struct D3D12Texture * tex = &this->texture[textureIndex];
|
||||||
|
|
||||||
|
HRESULT status = ID3D12GraphicsCommandList_Close(*tex->graphicsCommandList);
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to close command list", status);
|
DEBUG_WINERROR("Failed to close command list", status);
|
||||||
goto cleanup;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12CommandQueue_ExecuteCommandLists(*this->commandQueue,
|
ID3D12CommandQueue_ExecuteCommandLists(*this->commandQueue,
|
||||||
@ -492,7 +525,7 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to signal capture fence", status);
|
DEBUG_WINERROR("Failed to signal capture fence", status);
|
||||||
goto cleanup;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetEvent(this->event);
|
ResetEvent(this->event);
|
||||||
@ -501,7 +534,7 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to signal capture fence event", status);
|
DEBUG_WINERROR("Failed to signal capture fence event", status);
|
||||||
goto cleanup;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = ID3D12CommandQueue_Signal(*this->commandQueue,
|
status = ID3D12CommandQueue_Signal(*this->commandQueue,
|
||||||
@ -509,7 +542,7 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to signal texture fence", status);
|
DEBUG_WINERROR("Failed to signal texture fence", status);
|
||||||
goto cleanup;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = ID3D12Fence_SetEventOnCompletion(*tex->fence,
|
status = ID3D12Fence_SetEventOnCompletion(*tex->fence,
|
||||||
@ -517,18 +550,19 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to signal texture fence event", status);
|
DEBUG_WINERROR("Failed to signal texture fence event", status);
|
||||||
goto cleanup;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
fail = false;
|
result = true;
|
||||||
cleanup:
|
|
||||||
comRef_scopePop();
|
exit:
|
||||||
return !fail;
|
comRef_scopePop(); //push is in pre-copy
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CaptureResult d3d12_mapTexture(Texture * parent)
|
static CaptureResult d3d12_mapTexture(unsigned textureIndex, void ** map)
|
||||||
{
|
{
|
||||||
struct D3D12Texture * tex = parent->impl;
|
struct D3D12Texture * tex = &this->texture[textureIndex];
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
|
|
||||||
WaitForSingleObject(tex->event, INFINITE);
|
WaitForSingleObject(tex->event, INFINITE);
|
||||||
@ -553,7 +587,7 @@ static CaptureResult d3d12_mapTexture(Texture * parent)
|
|||||||
.Begin = 0,
|
.Begin = 0,
|
||||||
.End = this->pitch * this->height
|
.End = this->pitch * this->height
|
||||||
};
|
};
|
||||||
status = ID3D12Resource_Map(*tex->tex, 0, &range, &parent->map);
|
status = ID3D12Resource_Map(*tex->tex, 0, &range, map);
|
||||||
|
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
@ -564,9 +598,9 @@ static CaptureResult d3d12_mapTexture(Texture * parent)
|
|||||||
return CAPTURE_RESULT_OK;
|
return CAPTURE_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void d3d12_unmapTexture(Texture * parent)
|
static void d3d12_unmapTexture(unsigned textureIndex)
|
||||||
{
|
{
|
||||||
struct D3D12Texture * tex = parent->impl;
|
struct D3D12Texture * tex = &this->texture[textureIndex];
|
||||||
|
|
||||||
D3D12_RANGE range =
|
D3D12_RANGE range =
|
||||||
{
|
{
|
||||||
@ -574,7 +608,6 @@ static void d3d12_unmapTexture(Texture * parent)
|
|||||||
.End = 0
|
.End = 0
|
||||||
};
|
};
|
||||||
ID3D12Resource_Unmap(*tex->tex, 0, &range);
|
ID3D12Resource_Unmap(*tex->tex, 0, &range);
|
||||||
parent->map = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void d3d12_preRelease(void)
|
static void d3d12_preRelease(void)
|
||||||
@ -589,7 +622,10 @@ struct DXGICopyBackend copyBackendD3D12 =
|
|||||||
.create = d3d12_create,
|
.create = d3d12_create,
|
||||||
.configure = d3d12_configure,
|
.configure = d3d12_configure,
|
||||||
.free = d3d12_free,
|
.free = d3d12_free,
|
||||||
.copyFrame = d3d12_copyFrame,
|
.preCopy = d3d12_preCopy,
|
||||||
|
.copyFull = d3d12_copyFull,
|
||||||
|
.copyRect = d3d12_copyRect,
|
||||||
|
.postCopy = d3d12_postCopy,
|
||||||
.mapTexture = d3d12_mapTexture,
|
.mapTexture = d3d12_mapTexture,
|
||||||
.unmapTexture = d3d12_unmapTexture,
|
.unmapTexture = d3d12_unmapTexture,
|
||||||
.preRelease = d3d12_preRelease,
|
.preRelease = d3d12_preRelease,
|
||||||
|
@ -708,7 +708,7 @@ static bool dxgi_init(void)
|
|||||||
{
|
{
|
||||||
if (!strcasecmp(copyBackend, backends[i]->code))
|
if (!strcasecmp(copyBackend, backends[i]->code))
|
||||||
{
|
{
|
||||||
if (!backends[i]->create(this))
|
if (!backends[i]->create(this->maxTextures))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to initialize selected capture backend: %s", backends[i]->name);
|
DEBUG_ERROR("Failed to initialize selected capture backend: %s", backends[i]->name);
|
||||||
backends[i]->free();
|
backends[i]->free();
|
||||||
@ -795,7 +795,7 @@ static bool dxgi_deinit(void)
|
|||||||
Texture * tex = &this->texture[i];
|
Texture * tex = &this->texture[i];
|
||||||
if (!tex->map)
|
if (!tex->map)
|
||||||
continue;
|
continue;
|
||||||
this->backend->unmapTexture(tex);
|
this->backend->unmapTexture(i);
|
||||||
tex->map = NULL;
|
tex->map = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1099,7 +1099,12 @@ static CaptureResult dxgi_capture(void)
|
|||||||
|
|
||||||
unsigned pitch = 0;
|
unsigned pitch = 0;
|
||||||
LG_LOCK(this->deviceContextLock);
|
LG_LOCK(this->deviceContextLock);
|
||||||
if (!this->backend->configure(cols, rows, this->dxgiFormat, &pitch))
|
if (!this->backend->configure(
|
||||||
|
cols,
|
||||||
|
rows,
|
||||||
|
this->dxgiFormat,
|
||||||
|
this->bpp,
|
||||||
|
&pitch))
|
||||||
{
|
{
|
||||||
LG_UNLOCK(this->deviceContextLock);
|
LG_UNLOCK(this->deviceContextLock);
|
||||||
DEBUG_ERROR("Failed to configure the copy backend");
|
DEBUG_ERROR("Failed to configure the copy backend");
|
||||||
@ -1132,7 +1137,44 @@ static CaptureResult dxgi_capture(void)
|
|||||||
computeFrameDamage(tex);
|
computeFrameDamage(tex);
|
||||||
computeTexDamage(tex);
|
computeTexDamage(tex);
|
||||||
|
|
||||||
if (!this->backend->copyFrame(tex, dst))
|
if (!this->backend->preCopy(dst, this->texWIndex))
|
||||||
|
{
|
||||||
|
result = CAPTURE_RESULT_ERROR;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex->texDamageCount <= 0)
|
||||||
|
{
|
||||||
|
if (!this->backend->copyFull(dst, this->texWIndex))
|
||||||
|
{
|
||||||
|
// call this so the backend can cleanup
|
||||||
|
this->backend->postCopy(dst, this->texWIndex);
|
||||||
|
result = CAPTURE_RESULT_ERROR;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < tex->texDamageCount; ++i)
|
||||||
|
{
|
||||||
|
FrameDamageRect * rect = &tex->texDamageRects[i];
|
||||||
|
|
||||||
|
// correct the damage rect for BGR packed data
|
||||||
|
if (this->outputFormat == CAPTURE_FMT_BGR)
|
||||||
|
{
|
||||||
|
rect->x = (rect->x * 3 ) / 4; // round down
|
||||||
|
rect->width = (rect->width * 3 + 3) / 4; // round up
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->backend->copyRect(dst, this->texWIndex, rect))
|
||||||
|
{
|
||||||
|
result = CAPTURE_RESULT_ERROR;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->backend->postCopy(dst, this->texWIndex))
|
||||||
{
|
{
|
||||||
result = CAPTURE_RESULT_ERROR;
|
result = CAPTURE_RESULT_ERROR;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -1266,7 +1308,7 @@ static CaptureResult dxgi_waitFrame(CaptureFrame * frame, const size_t maxFrameS
|
|||||||
|
|
||||||
Texture * tex = &this->texture[this->texRIndex];
|
Texture * tex = &this->texture[this->texRIndex];
|
||||||
|
|
||||||
CaptureResult result = this->backend->mapTexture(tex);
|
CaptureResult result = this->backend->mapTexture(this->texRIndex, &tex->map);
|
||||||
if (result != CAPTURE_RESULT_OK)
|
if (result != CAPTURE_RESULT_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@ -1355,7 +1397,8 @@ static CaptureResult dxgi_getFrame(FrameBuffer * frame, int frameIndex)
|
|||||||
damage->count = -1;
|
damage->count = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->backend->unmapTexture(tex);
|
this->backend->unmapTexture(this->texRIndex);
|
||||||
|
tex->map = NULL;
|
||||||
tex->state = TEXTURE_STATE_UNUSED;
|
tex->state = TEXTURE_STATE_UNUSED;
|
||||||
|
|
||||||
if (++this->texRIndex == this->maxTextures)
|
if (++this->texRIndex == this->maxTextures)
|
||||||
@ -1549,6 +1592,36 @@ static void ppFreeAll(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IDXGIAdapter1 * dxgi_getAdapter(void)
|
||||||
|
{
|
||||||
|
return *this->adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D11Device * dxgi_getDevice(void)
|
||||||
|
{
|
||||||
|
return *this->device;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D11DeviceContext * dxgi_getContext(void)
|
||||||
|
{
|
||||||
|
return *this->deviceContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dxgi_contextLock(void)
|
||||||
|
{
|
||||||
|
LG_LOCK(this->deviceContextLock);
|
||||||
|
};
|
||||||
|
|
||||||
|
void dxgi_contextUnlock(void)
|
||||||
|
{
|
||||||
|
LG_UNLOCK(this->deviceContextLock);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool dxgi_debug(void)
|
||||||
|
{
|
||||||
|
return this->debug;
|
||||||
|
}
|
||||||
|
|
||||||
struct CaptureInterface Capture_DXGI =
|
struct CaptureInterface Capture_DXGI =
|
||||||
{
|
{
|
||||||
.shortName = "DXGI",
|
.shortName = "DXGI",
|
||||||
|
@ -50,7 +50,6 @@ typedef struct Texture
|
|||||||
unsigned int formatVer;
|
unsigned int formatVer;
|
||||||
volatile enum TextureState state;
|
volatile enum TextureState state;
|
||||||
void * map;
|
void * map;
|
||||||
uint64_t copyTime;
|
|
||||||
uint32_t damageRectsCount;
|
uint32_t damageRectsCount;
|
||||||
FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS];
|
FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS];
|
||||||
int texDamageCount;
|
int texDamageCount;
|
||||||
@ -63,11 +62,12 @@ typedef struct Texture
|
|||||||
}
|
}
|
||||||
Texture;
|
Texture;
|
||||||
|
|
||||||
struct FrameDamage
|
typedef struct FrameDamage
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
FrameDamageRect rects[KVMFR_MAX_DAMAGE_RECTS];
|
FrameDamageRect rects[KVMFR_MAX_DAMAGE_RECTS];
|
||||||
};
|
}
|
||||||
|
FrameDamage;
|
||||||
|
|
||||||
struct DXGIInterface
|
struct DXGIInterface
|
||||||
{
|
{
|
||||||
@ -122,4 +122,11 @@ struct DXGIInterface
|
|||||||
struct FrameDamage frameDamage[LGMP_Q_FRAME_LEN];
|
struct FrameDamage frameDamage[LGMP_Q_FRAME_LEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
IDXGIAdapter1 * dxgi_getAdapter(void);
|
||||||
|
ID3D11Device * dxgi_getDevice(void);
|
||||||
|
ID3D11DeviceContext * dxgi_getContext(void);
|
||||||
|
void dxgi_contextLock(void);
|
||||||
|
void dxgi_contextUnlock(void);
|
||||||
|
bool dxgi_debug(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -78,7 +78,7 @@ static bool rgb24_configure(void * opaque,
|
|||||||
|
|
||||||
if (!this.pshader)
|
if (!this.pshader)
|
||||||
{
|
{
|
||||||
this.width = *cols * 3 / 4;
|
this.width = (*cols * 3 + 3) / 4;
|
||||||
this.height = *rows;
|
this.height = *rows;
|
||||||
|
|
||||||
char sOutputWidth[6], sOutputHeight[6];
|
char sOutputWidth[6], sOutputHeight[6];
|
||||||
|
Loading…
Reference in New Issue
Block a user