mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
Updated bufferProducerFence. Updated nvgfxEventWait. Added better initialization validation to binder, etc. In bufferProducerDequeueBuffer(), use sizeof instead of a constant for the fence size. Updated g_gfxQueueBufferData. Fixed validation in _gfxGetNativeWindowID. Other changes.
This commit is contained in:
parent
428d0373a8
commit
63016db072
@ -3,9 +3,8 @@
|
||||
#include <switch/gfx/nvioctl.h>
|
||||
|
||||
typedef struct {
|
||||
u32 unk_x0;
|
||||
nvioctl_fence nv_fence;
|
||||
u32 unk_xc[0x18>>2];
|
||||
u32 is_valid;
|
||||
nvioctl_fence nv_fences[4];
|
||||
} PACKED bufferProducerFence;
|
||||
|
||||
typedef struct {
|
||||
|
@ -1,4 +1,4 @@
|
||||
Result nvgfxInitialize(void);
|
||||
void nvgfxExit(void);
|
||||
Result nvgfxEventInit(void);
|
||||
Result nvgfxEventWait(u32 syncpt_id, u32 threshold);
|
||||
Result nvgfxGetFramebuffer(u8 **buffer, size_t *size);
|
||||
|
@ -1,6 +1,8 @@
|
||||
#define BINDER_FIRST_CALL_TRANSACTION 0x1
|
||||
|
||||
typedef struct {
|
||||
bool created;
|
||||
bool initialized;
|
||||
Handle sessionHandle;
|
||||
s32 id;
|
||||
Handle nativeHandle;
|
||||
|
@ -4,6 +4,7 @@
|
||||
void binderCreateSession(binderSession *session, Handle sessionHandle, s32 id)
|
||||
{
|
||||
memset(session, 0, sizeof(binderSession));
|
||||
session->created = 1;
|
||||
session->sessionHandle = sessionHandle;
|
||||
session->id = id;
|
||||
session->nativeHandle = INVALID_HANDLE;
|
||||
@ -14,6 +15,9 @@ Result binderInitSession(binderSession *session, u32 unk0)
|
||||
{
|
||||
Result rc = 0;
|
||||
|
||||
if (!session->created) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
if (session->initialized) return MAKERESULT(MODULE_LIBNX, LIBNX_ALREADYINITIALIZED);
|
||||
|
||||
rc = binderAdjustRefcount(session, 1, 0);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
@ -41,6 +45,8 @@ Result binderInitSession(binderSession *session, u32 unk0)
|
||||
return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
|
||||
}
|
||||
|
||||
session->initialized = 1;
|
||||
|
||||
rc = ipcQueryPointerBufferSize(session->sessionHandle, &session->ipcBufferSize);
|
||||
|
||||
if (R_FAILED(rc)) {
|
||||
@ -57,13 +63,23 @@ Result binderInitSession(binderSession *session, u32 unk0)
|
||||
|
||||
void binderExitSession(binderSession *session)
|
||||
{
|
||||
binderAdjustRefcount(session, -1, 1);
|
||||
binderAdjustRefcount(session, -1, 0);
|
||||
if (!session->created) return;
|
||||
|
||||
if (session->nativeHandle != INVALID_HANDLE) {
|
||||
svcCloseHandle(session->nativeHandle);
|
||||
session->nativeHandle = INVALID_HANDLE;
|
||||
if (session->initialized) {
|
||||
binderAdjustRefcount(session, -1, 1);
|
||||
binderAdjustRefcount(session, -1, 0);
|
||||
|
||||
if (session->nativeHandle != INVALID_HANDLE) {
|
||||
svcCloseHandle(session->nativeHandle);
|
||||
session->nativeHandle = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
session->sessionHandle = INVALID_HANDLE;
|
||||
session->id = 0;
|
||||
|
||||
session->created = 0;
|
||||
session->initialized = 0;
|
||||
}
|
||||
|
||||
static Result _binderTransactParcel(
|
||||
@ -72,6 +88,8 @@ static Result _binderTransactParcel(
|
||||
void* parcel_reply, size_t parcel_reply_size,
|
||||
u32 flags)
|
||||
{
|
||||
if (!session->created || !session->initialized) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
@ -116,6 +134,8 @@ static Result _binderTransactParcelAuto(
|
||||
void* parcel_reply, size_t parcel_reply_size,
|
||||
u32 flags)
|
||||
{
|
||||
if (!session->created || !session->initialized) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
@ -193,6 +213,8 @@ Result binderTransactParcel(
|
||||
|
||||
Result binderAdjustRefcount(binderSession *session, s32 addval, s32 type)
|
||||
{
|
||||
if (!session->created) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
@ -230,6 +252,8 @@ Result binderAdjustRefcount(binderSession *session, s32 addval, s32 type)
|
||||
|
||||
Result binderGetNativeHandle(binderSession *session, u32 inval, Handle *handle_out)
|
||||
{
|
||||
if (!session->created) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
|
@ -103,8 +103,8 @@ Result bufferProducerDequeueBuffer(bool async, u32 width, u32 height, s32 format
|
||||
void* tmp_ptr;
|
||||
|
||||
tmp_ptr = parcelReadFlattenedObject(&parcel_reply, &tmpsize);
|
||||
if (tmp_ptr==NULL || tmpsize!=0x24) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
|
||||
if (fence) memcpy(fence, tmp_ptr, 0x24);
|
||||
if (tmp_ptr==NULL || tmpsize!=sizeof(bufferProducerFence)) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
|
||||
if (fence) memcpy(fence, tmp_ptr, sizeof(bufferProducerFence));
|
||||
}
|
||||
|
||||
int result = parcelReadInt32(&parcel_reply);
|
||||
|
@ -24,6 +24,7 @@ extern u32 __nx_applet_type;
|
||||
extern u32 g_nvgfx_totalframebufs;
|
||||
extern size_t g_nvgfx_singleframebuf_size;
|
||||
|
||||
//TODO: Let the user configure some of this?
|
||||
static bufferProducerQueueBufferInput g_gfxQueueBufferData = {
|
||||
.timestamp = 0x0,
|
||||
.isAutoTimestamp = 0x1,
|
||||
@ -31,27 +32,26 @@ static bufferProducerQueueBufferInput g_gfxQueueBufferData = {
|
||||
.scalingMode = 0x0,
|
||||
.transform = 0x2,
|
||||
.stickyTransform = 0x0,
|
||||
/*.unk = {0x0, 0x1},
|
||||
.unk = {0x0, 0x1},
|
||||
|
||||
.fence = {
|
||||
.unk_x0 = 0x1,
|
||||
.nv_fence = {
|
||||
.id = 0x42,
|
||||
.value = 0x13f4,
|
||||
.is_valid = 0x1,
|
||||
.nv_fences = {
|
||||
{
|
||||
.id = /*0x42*/0xffffffff,
|
||||
.value = /*0x13f4*/0x0,
|
||||
},
|
||||
{0xffffffff, 0x0}, {0xffffffff, 0x0}, {0xffffffff, 0x0},
|
||||
},
|
||||
.unk_xc = {
|
||||
0xffffffff, 0x0, 0xffffffff, 0x0, 0xffffffff, 0x0
|
||||
},
|
||||
}*/
|
||||
}
|
||||
};
|
||||
|
||||
static Result _gfxGetNativeWindowID(u8 *buf, u64 size, s32 *out_ID) {
|
||||
u32 *bufptr = (u32*)buf;
|
||||
|
||||
//Validate ParcelData{Size|Offset}.
|
||||
if((u64)bufptr[1] >= size || (u64)bufptr[0] >= size || ((u64)bufptr[1])+((u64)bufptr[0]) >= size) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
|
||||
if((u64)bufptr[1] > size || (u64)bufptr[0] > size || ((u64)bufptr[1])+((u64)bufptr[0]) > size) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
|
||||
if(bufptr[0] < 0xc) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
|
||||
|
||||
//bufptr = start of ParcelData
|
||||
bufptr = (u32*)&buf[bufptr[1]];
|
||||
|
||||
@ -70,6 +70,8 @@ static Result _gfxDequeueBuffer(bufferProducerFence *fence) {
|
||||
|
||||
rc = bufferProducerDequeueBuffer(/*1*/0, 1280, 720, 0, 0x300, &g_gfxCurrentProducerBuffer, fence);
|
||||
|
||||
//if (R_SUCCEEDED(rc) && fence) rc = nvgfxEventWait(fence->nv_fences[0].id, fence->nv_fences[0].value);
|
||||
|
||||
if (R_SUCCEEDED(rc)) g_gfxCurrentBuffer = (g_gfxCurrentBuffer + 1) & (g_nvgfx_totalframebufs-1);
|
||||
|
||||
return rc;
|
||||
@ -161,11 +163,9 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L
|
||||
}
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvgfxEventInit();
|
||||
|
||||
if (R_SUCCEEDED(rc)) svcSleepThread(3000000000);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer(NULL);
|
||||
if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer(&g_gfx_DequeueBuffer_fence);
|
||||
|
||||
/*if (R_SUCCEEDED(rc)) { //Workaround a gfx display issue.
|
||||
for(i=0; i<2; i++)gfxWaitForVsync();
|
||||
@ -292,6 +292,11 @@ void gfxSwapBuffers() {
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer(&g_gfx_DequeueBuffer_fence);
|
||||
|
||||
#ifdef BUFFERSWAP_DELAY_HACK
|
||||
gfxWaitForVsync();
|
||||
gfxWaitForVsync();
|
||||
#endif
|
||||
|
||||
if (R_FAILED(rc)) fatalSimple(rc);
|
||||
}
|
||||
|
||||
|
@ -442,14 +442,14 @@ void nvgfxExit(void) {
|
||||
g_nvgfxInitialized = 0;
|
||||
}
|
||||
|
||||
Result nvgfxEventInit(void) {
|
||||
Result nvgfxEventWait(u32 syncpt_id, u32 threshold) {
|
||||
Result rc=0;
|
||||
|
||||
/*if (R_SUCCEEDED(rc)) {
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
do {
|
||||
rc = nvioctlNvhostCtrl_EventWait(g_nvgfx_fd_nvhostctrl, 0x42, 0x1ca7, 0x64, 0, &g_nvgfx_nvhostctrl_eventres);
|
||||
rc = nvioctlNvhostCtrl_EventWait(g_nvgfx_fd_nvhostctrl, /*0x42, 0x1ca7*/syncpt_id, threshold, 0x64, 0, &g_nvgfx_nvhostctrl_eventres);
|
||||
} while(rc==5);//timeout error
|
||||
}*/
|
||||
}
|
||||
|
||||
//Currently broken.
|
||||
//if (R_SUCCEEDED(rc)) rc = nvQueryEvent(g_nvgfx_fd_nvhostctrl, g_nvgfx_nvhostctrl_eventres, &g_nvgfx_nvhostctrl_eventhandle);
|
||||
|
Loading…
Reference in New Issue
Block a user