mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-22 13:02:38 +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>
|
#include <switch/gfx/nvioctl.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 unk_x0;
|
u32 is_valid;
|
||||||
nvioctl_fence nv_fence;
|
nvioctl_fence nv_fences[4];
|
||||||
u32 unk_xc[0x18>>2];
|
|
||||||
} PACKED bufferProducerFence;
|
} PACKED bufferProducerFence;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Result nvgfxInitialize(void);
|
Result nvgfxInitialize(void);
|
||||||
void nvgfxExit(void);
|
void nvgfxExit(void);
|
||||||
Result nvgfxEventInit(void);
|
Result nvgfxEventWait(u32 syncpt_id, u32 threshold);
|
||||||
Result nvgfxGetFramebuffer(u8 **buffer, size_t *size);
|
Result nvgfxGetFramebuffer(u8 **buffer, size_t *size);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#define BINDER_FIRST_CALL_TRANSACTION 0x1
|
#define BINDER_FIRST_CALL_TRANSACTION 0x1
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
bool created;
|
||||||
|
bool initialized;
|
||||||
Handle sessionHandle;
|
Handle sessionHandle;
|
||||||
s32 id;
|
s32 id;
|
||||||
Handle nativeHandle;
|
Handle nativeHandle;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
void binderCreateSession(binderSession *session, Handle sessionHandle, s32 id)
|
void binderCreateSession(binderSession *session, Handle sessionHandle, s32 id)
|
||||||
{
|
{
|
||||||
memset(session, 0, sizeof(binderSession));
|
memset(session, 0, sizeof(binderSession));
|
||||||
|
session->created = 1;
|
||||||
session->sessionHandle = sessionHandle;
|
session->sessionHandle = sessionHandle;
|
||||||
session->id = id;
|
session->id = id;
|
||||||
session->nativeHandle = INVALID_HANDLE;
|
session->nativeHandle = INVALID_HANDLE;
|
||||||
@ -14,6 +15,9 @@ Result binderInitSession(binderSession *session, u32 unk0)
|
|||||||
{
|
{
|
||||||
Result rc = 0;
|
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);
|
rc = binderAdjustRefcount(session, 1, 0);
|
||||||
|
|
||||||
if (R_FAILED(rc))
|
if (R_FAILED(rc))
|
||||||
@ -41,6 +45,8 @@ Result binderInitSession(binderSession *session, u32 unk0)
|
|||||||
return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
|
return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session->initialized = 1;
|
||||||
|
|
||||||
rc = ipcQueryPointerBufferSize(session->sessionHandle, &session->ipcBufferSize);
|
rc = ipcQueryPointerBufferSize(session->sessionHandle, &session->ipcBufferSize);
|
||||||
|
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
@ -57,6 +63,9 @@ Result binderInitSession(binderSession *session, u32 unk0)
|
|||||||
|
|
||||||
void binderExitSession(binderSession *session)
|
void binderExitSession(binderSession *session)
|
||||||
{
|
{
|
||||||
|
if (!session->created) return;
|
||||||
|
|
||||||
|
if (session->initialized) {
|
||||||
binderAdjustRefcount(session, -1, 1);
|
binderAdjustRefcount(session, -1, 1);
|
||||||
binderAdjustRefcount(session, -1, 0);
|
binderAdjustRefcount(session, -1, 0);
|
||||||
|
|
||||||
@ -66,12 +75,21 @@ void binderExitSession(binderSession *session)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session->sessionHandle = INVALID_HANDLE;
|
||||||
|
session->id = 0;
|
||||||
|
|
||||||
|
session->created = 0;
|
||||||
|
session->initialized = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static Result _binderTransactParcel(
|
static Result _binderTransactParcel(
|
||||||
binderSession *session, u32 code,
|
binderSession *session, u32 code,
|
||||||
void* parcel_data, size_t parcel_data_size,
|
void* parcel_data, size_t parcel_data_size,
|
||||||
void* parcel_reply, size_t parcel_reply_size,
|
void* parcel_reply, size_t parcel_reply_size,
|
||||||
u32 flags)
|
u32 flags)
|
||||||
{
|
{
|
||||||
|
if (!session->created || !session->initialized) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||||
|
|
||||||
IpcCommand c;
|
IpcCommand c;
|
||||||
ipcInitialize(&c);
|
ipcInitialize(&c);
|
||||||
|
|
||||||
@ -116,6 +134,8 @@ static Result _binderTransactParcelAuto(
|
|||||||
void* parcel_reply, size_t parcel_reply_size,
|
void* parcel_reply, size_t parcel_reply_size,
|
||||||
u32 flags)
|
u32 flags)
|
||||||
{
|
{
|
||||||
|
if (!session->created || !session->initialized) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||||
|
|
||||||
IpcCommand c;
|
IpcCommand c;
|
||||||
ipcInitialize(&c);
|
ipcInitialize(&c);
|
||||||
|
|
||||||
@ -193,6 +213,8 @@ Result binderTransactParcel(
|
|||||||
|
|
||||||
Result binderAdjustRefcount(binderSession *session, s32 addval, s32 type)
|
Result binderAdjustRefcount(binderSession *session, s32 addval, s32 type)
|
||||||
{
|
{
|
||||||
|
if (!session->created) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||||
|
|
||||||
IpcCommand c;
|
IpcCommand c;
|
||||||
ipcInitialize(&c);
|
ipcInitialize(&c);
|
||||||
|
|
||||||
@ -230,6 +252,8 @@ Result binderAdjustRefcount(binderSession *session, s32 addval, s32 type)
|
|||||||
|
|
||||||
Result binderGetNativeHandle(binderSession *session, u32 inval, Handle *handle_out)
|
Result binderGetNativeHandle(binderSession *session, u32 inval, Handle *handle_out)
|
||||||
{
|
{
|
||||||
|
if (!session->created) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||||
|
|
||||||
IpcCommand c;
|
IpcCommand c;
|
||||||
ipcInitialize(&c);
|
ipcInitialize(&c);
|
||||||
|
|
||||||
|
@ -103,8 +103,8 @@ Result bufferProducerDequeueBuffer(bool async, u32 width, u32 height, s32 format
|
|||||||
void* tmp_ptr;
|
void* tmp_ptr;
|
||||||
|
|
||||||
tmp_ptr = parcelReadFlattenedObject(&parcel_reply, &tmpsize);
|
tmp_ptr = parcelReadFlattenedObject(&parcel_reply, &tmpsize);
|
||||||
if (tmp_ptr==NULL || tmpsize!=0x24) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
|
if (tmp_ptr==NULL || tmpsize!=sizeof(bufferProducerFence)) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
|
||||||
if (fence) memcpy(fence, tmp_ptr, 0x24);
|
if (fence) memcpy(fence, tmp_ptr, sizeof(bufferProducerFence));
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = parcelReadInt32(&parcel_reply);
|
int result = parcelReadInt32(&parcel_reply);
|
||||||
|
@ -24,6 +24,7 @@ extern u32 __nx_applet_type;
|
|||||||
extern u32 g_nvgfx_totalframebufs;
|
extern u32 g_nvgfx_totalframebufs;
|
||||||
extern size_t g_nvgfx_singleframebuf_size;
|
extern size_t g_nvgfx_singleframebuf_size;
|
||||||
|
|
||||||
|
//TODO: Let the user configure some of this?
|
||||||
static bufferProducerQueueBufferInput g_gfxQueueBufferData = {
|
static bufferProducerQueueBufferInput g_gfxQueueBufferData = {
|
||||||
.timestamp = 0x0,
|
.timestamp = 0x0,
|
||||||
.isAutoTimestamp = 0x1,
|
.isAutoTimestamp = 0x1,
|
||||||
@ -31,27 +32,26 @@ static bufferProducerQueueBufferInput g_gfxQueueBufferData = {
|
|||||||
.scalingMode = 0x0,
|
.scalingMode = 0x0,
|
||||||
.transform = 0x2,
|
.transform = 0x2,
|
||||||
.stickyTransform = 0x0,
|
.stickyTransform = 0x0,
|
||||||
/*.unk = {0x0, 0x1},
|
.unk = {0x0, 0x1},
|
||||||
|
|
||||||
.fence = {
|
.fence = {
|
||||||
.unk_x0 = 0x1,
|
.is_valid = 0x1,
|
||||||
.nv_fence = {
|
.nv_fences = {
|
||||||
.id = 0x42,
|
{
|
||||||
.value = 0x13f4,
|
.id = /*0x42*/0xffffffff,
|
||||||
|
.value = /*0x13f4*/0x0,
|
||||||
},
|
},
|
||||||
.unk_xc = {
|
{0xffffffff, 0x0}, {0xffffffff, 0x0}, {0xffffffff, 0x0},
|
||||||
0xffffffff, 0x0, 0xffffffff, 0x0, 0xffffffff, 0x0
|
|
||||||
},
|
},
|
||||||
}*/
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static Result _gfxGetNativeWindowID(u8 *buf, u64 size, s32 *out_ID) {
|
static Result _gfxGetNativeWindowID(u8 *buf, u64 size, s32 *out_ID) {
|
||||||
u32 *bufptr = (u32*)buf;
|
u32 *bufptr = (u32*)buf;
|
||||||
|
|
||||||
//Validate ParcelData{Size|Offset}.
|
//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);
|
if(bufptr[0] < 0xc) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
|
||||||
|
|
||||||
//bufptr = start of ParcelData
|
//bufptr = start of ParcelData
|
||||||
bufptr = (u32*)&buf[bufptr[1]];
|
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);
|
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);
|
if (R_SUCCEEDED(rc)) g_gfxCurrentBuffer = (g_gfxCurrentBuffer + 1) & (g_nvgfx_totalframebufs-1);
|
||||||
|
|
||||||
return rc;
|
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)) 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.
|
/*if (R_SUCCEEDED(rc)) { //Workaround a gfx display issue.
|
||||||
for(i=0; i<2; i++)gfxWaitForVsync();
|
for(i=0; i<2; i++)gfxWaitForVsync();
|
||||||
@ -292,6 +292,11 @@ void gfxSwapBuffers() {
|
|||||||
|
|
||||||
if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer(&g_gfx_DequeueBuffer_fence);
|
if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer(&g_gfx_DequeueBuffer_fence);
|
||||||
|
|
||||||
|
#ifdef BUFFERSWAP_DELAY_HACK
|
||||||
|
gfxWaitForVsync();
|
||||||
|
gfxWaitForVsync();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (R_FAILED(rc)) fatalSimple(rc);
|
if (R_FAILED(rc)) fatalSimple(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,14 +442,14 @@ void nvgfxExit(void) {
|
|||||||
g_nvgfxInitialized = 0;
|
g_nvgfxInitialized = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result nvgfxEventInit(void) {
|
Result nvgfxEventWait(u32 syncpt_id, u32 threshold) {
|
||||||
Result rc=0;
|
Result rc=0;
|
||||||
|
|
||||||
/*if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
do {
|
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
|
} while(rc==5);//timeout error
|
||||||
}*/
|
}
|
||||||
|
|
||||||
//Currently broken.
|
//Currently broken.
|
||||||
//if (R_SUCCEEDED(rc)) rc = nvQueryEvent(g_nvgfx_fd_nvhostctrl, g_nvgfx_nvhostctrl_eventres, &g_nvgfx_nvhostctrl_eventhandle);
|
//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