diff --git a/host/platform/Windows/capture/NVFBC/src/nvfbc.c b/host/platform/Windows/capture/NVFBC/src/nvfbc.c index f2bf520e..cf5b392a 100644 --- a/host/platform/Windows/capture/NVFBC/src/nvfbc.c +++ b/host/platform/Windows/capture/NVFBC/src/nvfbc.c @@ -36,7 +36,7 @@ #include #include "wrapper.h" -#define DIFF_MAP_DIM(x) ((x + 127) / 128) +#define DIFF_MAP_DIM(x, shift) (((x) + (1 << (shift)) - 1) >> (shift)) struct FrameInfo { @@ -64,6 +64,7 @@ struct iface uint8_t * frameBuffer; uint8_t * diffMap; + int diffShift; NvFBCFrameGrabInfo grabInfo; @@ -130,6 +131,13 @@ static void nvfbc_initOptions(void) .type = OPTION_TYPE_BOOL, .value.x_bool = true }, + { + .module = "nvfbc", + .name = "diffRes", + .description = "The resolution of the diff map", + .type = OPTION_TYPE_INT, + .value.x_int = 128 + }, {0} }; @@ -186,6 +194,10 @@ static bool nvfbc_init(void) free(privData); return false; } + + int diffRes = option_get_bool("nvfbc", "diffRes"); + enum DiffMapBlockSize blockSize; + NvFBCGetDiffMapBlockSize(diffRes, &blockSize, &this->diffShift, privData, privDataLen); free(privData); getDesktopSize(&this->width, &this->height); @@ -197,7 +209,7 @@ static bool nvfbc_init(void) !this->seperateCursor, this->seperateCursor, true, - DIFFMAP_BLOCKSIZE_128X128, + blockSize, (void **)&this->frameBuffer, (void **)&this->diffMap, &event @@ -221,6 +233,10 @@ static bool nvfbc_init(void) this->forceCompositionCreated = true; } + if (diffRes != (1 << this->diffShift)) + DEBUG_WARN("DiffMap block size not supported: %dx%d", diffRes, diffRes); + + DEBUG_INFO("DiffMap block : %dx%d", 1 << this->diffShift, 1 << this->diffShift); DEBUG_INFO("Cursor mode : %s", this->seperateCursor ? "decoupled" : "integrated"); for (int i = 0; i < LGMP_Q_FRAME_LEN; ++i) @@ -228,7 +244,10 @@ static bool nvfbc_init(void) this->frameInfo[i].width = 0; this->frameInfo[i].height = 0; this->frameInfo[i].wasFresh = false; - this->frameInfo[i].diffMap = malloc(DIFF_MAP_DIM(this->maxWidth) * DIFF_MAP_DIM(this->maxHeight)); + this->frameInfo[i].diffMap = malloc( + DIFF_MAP_DIM(this->maxWidth, this->diffShift) * + DIFF_MAP_DIM(this->maxHeight, this->diffShift) + ); if (!this->frameInfo[i].diffMap) { DEBUG_ERROR("Failed to allocate memory for diffMaps"); @@ -315,8 +334,8 @@ static CaptureResult nvfbc_capture(void) return result; bool changed = false; - const unsigned int h = DIFF_MAP_DIM(this->height); - const unsigned int w = DIFF_MAP_DIM(this->width); + const unsigned int h = DIFF_MAP_DIM(this->height, this->diffShift); + const unsigned int w = DIFF_MAP_DIM(this->width, this->diffShift); for (unsigned int y = 0; y < h; ++y) for (unsigned int x = 0; x < w; ++x) if (this->diffMap[(y*w)+x]) @@ -364,8 +383,8 @@ static void dsUnion(struct DisjointSet * ds, int a, int b) static void updateDamageRects(CaptureFrame * frame) { - const unsigned int h = DIFF_MAP_DIM(this->height); - const unsigned int w = DIFF_MAP_DIM(this->width); + const unsigned int h = DIFF_MAP_DIM(this->height, this->diffShift); + const unsigned int w = DIFF_MAP_DIM(this->width, this->diffShift); struct DisjointSet ds[w * h]; @@ -395,10 +414,10 @@ static void updateDamageRects(CaptureFrame * frame) goto done; } - int x1 = ds[y * w + x].x1 * 128; - int y1 = ds[y * w + x].y1 * 128; - int x2 = min((ds[y * w + x].x2 + 1) * 128, this->width); - int y2 = min((ds[y * w + x].y2 + 1) * 128, this->height); + int x1 = ds[y * w + x].x1 << this->diffShift; + int y1 = ds[y * w + x].y1 << this->diffShift; + int x2 = min((ds[y * w + x].x2 + 1) << this->diffShift, this->width); + int y2 = min((ds[y * w + x].y2 + 1) << this->diffShift, this->height); frame->damageRects[rectId++] = (FrameDamageRect) { .x = x1, .y = y1, @@ -473,8 +492,8 @@ inline static void rectCopyUnaligned(uint8_t * dest, uint8_t * src, int ystart, static CaptureResult nvfbc_getFrame(FrameBuffer * frame, const unsigned int height, int frameIndex) { - const unsigned int h = DIFF_MAP_DIM(this->height); - const unsigned int w = DIFF_MAP_DIM(this->width); + const unsigned int h = DIFF_MAP_DIM(this->height, this->diffShift); + const unsigned int w = DIFF_MAP_DIM(this->width, this->diffShift); uint8_t * frameData = framebuffer_get_data(frame); struct FrameInfo * info = this->frameInfo + frameIndex; @@ -484,8 +503,8 @@ static CaptureResult nvfbc_getFrame(FrameBuffer * frame, for (unsigned int y = 0; y < h; ++y) { - const unsigned int ystart = y * 128; - const unsigned int yend = min(height, (y + 1) * 128); + const unsigned int ystart = y << this->diffShift; + const unsigned int yend = min(height, (y + 1) << this->diffShift); for (unsigned int x = 0; x < w; ) { @@ -499,8 +518,8 @@ static CaptureResult nvfbc_getFrame(FrameBuffer * frame, while (x2 < w && ((!wasFresh && info->diffMap[y * w + x2]) || this->diffMap[y * w + x2])) ++x2; - unsigned int width = (min(x2 * 128, this->grabStride) - x * 128) * 4; - rectCopyUnaligned(frameData, this->frameBuffer, ystart, yend, x * 512, + unsigned int width = (min(x2 << this->diffShift, this->grabStride) - (x << this->diffShift)) * 4; + rectCopyUnaligned(frameData, this->frameBuffer, ystart, yend, x << (2 + this->diffShift), this->grabStride * 4, width); x = x2; diff --git a/host/platform/Windows/capture/NVFBC/src/wrapper.cpp b/host/platform/Windows/capture/NVFBC/src/wrapper.cpp index 0ed5729a..0d5d8a2c 100644 --- a/host/platform/Windows/capture/NVFBC/src/wrapper.cpp +++ b/host/platform/Windows/capture/NVFBC/src/wrapper.cpp @@ -145,6 +145,54 @@ bool NvFBCToSysCreate( return true; } +void NvFBCGetDiffMapBlockSize( + int diffRes, + enum DiffMapBlockSize * diffMapBlockSize, + int * diffShift, + void * privData, + unsigned int privDataSize +) +{ + NvFBCStatusEx status = {0}; + status.dwVersion = NVFBC_STATUS_VER; + status.dwPrivateDataSize = privDataSize; + status.pPrivateData = privData; + + NVFBCRESULT result = nvapi.getStatusEx(&status); + if (result != NVFBC_SUCCESS) + status.bSupportConfigurableDiffMap = FALSE; + + if (!status.bSupportConfigurableDiffMap) + { + *diffMapBlockSize = DIFFMAP_BLOCKSIZE_128X128; + *diffShift = 7; + return; + } + + switch (diffRes) + { + case 16: + *diffMapBlockSize = DIFFMAP_BLOCKSIZE_16X16; + *diffShift = 4; + break; + + case 32: + *diffMapBlockSize = DIFFMAP_BLOCKSIZE_32X32; + *diffShift = 5; + break; + + case 64: + *diffMapBlockSize = DIFFMAP_BLOCKSIZE_64X64; + *diffShift = 6; + break; + + default: + *diffMapBlockSize = DIFFMAP_BLOCKSIZE_128X128; + *diffShift = 7; + break; + } +} + void NvFBCToSysRelease(NvFBCHandle * handle) { if (!*handle) diff --git a/host/platform/Windows/capture/NVFBC/src/wrapper.h b/host/platform/Windows/capture/NVFBC/src/wrapper.h index f64fd519..0f0f184b 100644 --- a/host/platform/Windows/capture/NVFBC/src/wrapper.h +++ b/host/platform/Windows/capture/NVFBC/src/wrapper.h @@ -60,6 +60,14 @@ bool NvFBCToSysCreate( ); void NvFBCToSysRelease(NvFBCHandle * handle); +void NvFBCGetDiffMapBlockSize( + int diffRes, + enum DiffMapBlockSize * diffMapBlockSize, + int * diffShift, + void * privData, + unsigned int privDataSize +); + bool NvFBCToSysSetup( NvFBCHandle handle, enum BufferFormat format,