mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
Implemented nvioctlNvmap_FromID() and nvioctlNvmap_GetID().
Added PARCEL_LOGGING define in parcel.c. Fixed the 'code' value used in gfxproducerQueueBuffer(). Moved some gfxproducer init into nvgfx. Moved some nvgfx event init into nvgfxEventInit(). Updated the code using gfxproducerBufferInit() for setting the nvmap-handles. Disabled a nvQueryEvent() call which now fails. Other changes. The setup framebuf/windowbuf is now displayed.
This commit is contained in:
parent
24fa9b0f4b
commit
b577367011
@ -1,2 +1,3 @@
|
||||
Result nvgfxInitialize(void);
|
||||
void nvgfxExit(void);
|
||||
Result nvgfxEventInit(void);
|
||||
|
@ -92,7 +92,9 @@ Result nvioctlNvhostAsGpu_GetVARegions(u32 fd, nvioctl_va_region regions[2]);
|
||||
Result nvioctlNvhostAsGpu_InitializeEx(u32 fd, u32 big_page_size);
|
||||
|
||||
Result nvioctlNvmap_Create(u32 fd, u32 size, u32 *nvmap_handle);
|
||||
Result nvioctlNvmap_FromID(u32 fd, u32 id, u32 *nvmap_handle);
|
||||
Result nvioctlNvmap_Alloc(u32 fd, u32 nvmap_handle, u32 heapmask, u32 flags, u32 align, u8 kind, void* addr);
|
||||
Result nvioctlNvmap_GetID(u32 fd, u32 nvmap_handle, u32 *id);
|
||||
|
||||
Result nvioctlChannel_SetNvmapFd(u32 fd, u32 nvmap_fd);
|
||||
Result nvioctlChannel_SubmitGPFIFO(u32 fd, nvioctl_gpfifo_entry *entries, u32 num_entries, u32 flags, nvioctl_fence *fence_out);
|
||||
|
@ -24,38 +24,6 @@ static u32 g_gfxQueueBufferData[0x5c>>2] = {
|
||||
0xffffffff, 0x0,
|
||||
0xffffffff, 0x0, 0xffffffff, 0x0};
|
||||
|
||||
static u32 g_gfxBufferInitData[0x178>>2] = {
|
||||
0x1, 0x16c, 0x0,
|
||||
0x47424652,
|
||||
1280, 720,
|
||||
1280,
|
||||
0x1, 0xb00, 0x2a, 0x0,
|
||||
0x0, 0x51, 0xffffffff, 0xcb8,
|
||||
0x0, 0xdaffcaff, 0x2a, 0x0,
|
||||
0xb00, 0x1, 0x1, 1280,
|
||||
0x3c0000, 0x1, 0x0, 1280,
|
||||
720, 0x532120, 0x1, 0x3,
|
||||
0x1400, 0xcb8,
|
||||
0x0,
|
||||
0xfe,
|
||||
0x4, 0x0, 0x0, 0x0,
|
||||
0x0, 0x3c0000, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0,
|
||||
0x0, 0x0 //Unknown, some timestamp perhaps?
|
||||
};
|
||||
|
||||
static Result _gfxGetNativeWindowID(u8 *buf, u64 size, s32 *out_ID) {
|
||||
u32 *bufptr = (u32*)buf;
|
||||
|
||||
@ -94,9 +62,7 @@ static Result _gfxQueueBuffer(s32 buf) {
|
||||
|
||||
static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 LayerFlags, u64 LayerId, nvServiceType nv_servicetype, size_t nv_transfermem_size) {
|
||||
Result rc=0;
|
||||
s32 tmp=0;
|
||||
u32 i=0;
|
||||
u64 *ptr64 = (u64*)g_gfxBufferInitData;
|
||||
|
||||
if(g_gfxInitialized)return 0;
|
||||
|
||||
@ -124,23 +90,11 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvInitialize(nv_servicetype, nv_transfermem_size);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvgfxInitialize();
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = gfxproducerInitialize(&g_gfxBinderSession);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = gfxproducerConnect(2, 0);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = gfxproducerQuery(2, &tmp);//"NATIVE_WINDOW_FORMAT"
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
for(i=0; i<2; i++) {
|
||||
g_gfxBufferInitData[0xa] = i;
|
||||
g_gfxBufferInitData[0x21] = 0x3c0000*i;
|
||||
ptr64[0x170>>3] = svcGetSystemTick();
|
||||
rc = gfxproducerBufferInit(i, (u8*)g_gfxBufferInitData);
|
||||
if (R_FAILED(rc)) break;
|
||||
}
|
||||
}
|
||||
if (R_SUCCEEDED(rc)) rc = nvgfxInitialize();
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
for(i=0; i<2; i++) {
|
||||
@ -150,16 +104,20 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L
|
||||
rc = gfxproducerRequestBuffer(i);//reply_parcel currently contains an error, presumably due to _gfxDequeueBuffer() failing as mentioned above.
|
||||
if (R_FAILED(rc)) break;
|
||||
|
||||
//Officially, nvioctlNvmap_FromID() and nvioctlChannel_SubmitGPFIFO() are used here.
|
||||
|
||||
rc = _gfxQueueBuffer(i);//reply_parcel currently contains the same error as gfxproducerRequestBuffer() above.
|
||||
if (R_FAILED(rc)) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvgfxEventInit();
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer();
|
||||
|
||||
if (R_FAILED(rc)) {
|
||||
gfxproducerExit();
|
||||
nvgfxExit();
|
||||
gfxproducerExit();
|
||||
nvExit();
|
||||
binderExitSession(&g_gfxBinderSession);
|
||||
viCloseLayer(&g_gfxLayer);
|
||||
@ -197,9 +155,10 @@ void gfxInitDefault(void) {
|
||||
void gfxExit(void) {
|
||||
if(!g_gfxInitialized)return;
|
||||
|
||||
nvgfxExit();
|
||||
|
||||
gfxproducerExit();
|
||||
|
||||
nvgfxExit();
|
||||
nvExit();
|
||||
|
||||
binderExitSession(&g_gfxBinderSession);
|
||||
|
@ -94,7 +94,7 @@ Result gfxproducerQueueBuffer(s32 buf, u8 input[0x5c]) {
|
||||
parcelWriteInt32(&parcel, buf);
|
||||
parcelWriteData(&parcel, input, 0x5c);
|
||||
|
||||
rc = parcelTransact(g_gfxproducerBinderSession, DEQUEUE_BUFFER, &parcel, &parcel_reply);
|
||||
rc = parcelTransact(g_gfxproducerBinderSession, QUEUE_BUFFER, &parcel, &parcel_reply);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
//TODO: parse reply
|
||||
|
@ -37,6 +37,40 @@ static nvmapobj nvmap_objs[18];
|
||||
|
||||
static u64 nvmap_obj6_mapbuffer_xdb_offset;
|
||||
|
||||
static u32 g_gfxprod_BufferInitData[0x178>>2] = {
|
||||
0x1, 0x16c, 0x0,
|
||||
0x47424652,
|
||||
1280, 720,
|
||||
1280,
|
||||
0x1, 0xb00, 0x2a, 0x0,
|
||||
0x0, 0x51, 0xffffffff,
|
||||
0x0, //nvmap handle
|
||||
0x0, 0xdaffcaff, 0x2a, 0x0,
|
||||
0xb00, 0x1, 0x1, 1280,
|
||||
0x3c0000, 0x1, 0x0, 1280,
|
||||
720, 0x532120, 0x1, 0x3,
|
||||
0x1400,
|
||||
0x0, //nvmap handle
|
||||
0x0,
|
||||
0xfe,
|
||||
0x4, 0x0, 0x0, 0x0,
|
||||
0x0, 0x3c0000, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0,
|
||||
0x0, 0x0 //Unknown, some timestamp perhaps?
|
||||
};
|
||||
|
||||
Result nvmapobjInitialize(nvmapobj *obj, size_t size) {
|
||||
Result rc=0;
|
||||
|
||||
@ -83,7 +117,10 @@ Result nvmapobjSetup(nvmapobj *obj, u32 heapmask, u32 flags, u32 align, u8 kind)
|
||||
|
||||
Result nvgfxInitialize(void) {
|
||||
Result rc=0;
|
||||
u32 pos=0;
|
||||
u32 pos=0, i=0;
|
||||
s32 tmp=0;
|
||||
u32 tmpval=0;
|
||||
u64 *ptr64 = (u64*)g_gfxprod_BufferInitData;
|
||||
if(g_nvgfxInitialized)return 0;
|
||||
|
||||
u32 zcullbind_data[4] = {0x58000, 0x5, 0x2, 0x0};
|
||||
@ -151,7 +188,8 @@ Result nvgfxInitialize(void) {
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_ZCullGetCtxSize(g_nvgfx_fd_nvhostctrlgpu, &g_nvgfx_zcullctxsize);
|
||||
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_ZCullGetInfo(g_nvgfx_fd_nvhostctrlgpu, g_nvgfx_zcullinfo);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvQueryEvent(g_nvgfx_fd_nvhostctrlgpu, 2, &g_nvgfx_nvhostctrlgpu_event2);
|
||||
//Currently broken.
|
||||
//if (R_SUCCEEDED(rc)) rc = nvQueryEvent(g_nvgfx_fd_nvhostctrlgpu, 2, &g_nvgfx_nvhostctrlgpu_event2);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvOpen(&g_nvgfx_fd_nvhostasgpu, "/dev/nvhost-as-gpu");
|
||||
|
||||
@ -242,7 +280,35 @@ Result nvgfxInitialize(void) {
|
||||
rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 0x100, pos<3 ? 0xdb : 0x86, framebuf_nvmap_handle, 0, pos*0x3c0000, 0x3c0000, nvmap_obj6_mapbuffer_xdb_offset, NULL);
|
||||
if (R_FAILED(rc)) break;
|
||||
|
||||
//Officially NVMAP_IOC_GET_ID, NVMAP_IOC_FROM_ID, NVMAP_IOC_GET_ID, and NVMAP_IOC_FROM_ID are used after the second *MapBufferEx.
|
||||
if(pos==2) {
|
||||
rc = gfxproducerQuery(2, &tmp);//"NATIVE_WINDOW_FORMAT"
|
||||
if (R_FAILED(rc)) break;
|
||||
|
||||
for(i=0; i<2; i++) {
|
||||
tmpval = 0;
|
||||
rc = nvioctlNvmap_GetID(g_nvgfx_fd_nvmap, nvmap_objs[6].handle, &tmpval);
|
||||
if (R_FAILED(rc)) break;
|
||||
|
||||
if(tmpval==~0) {
|
||||
rc = 6;//official error
|
||||
break;
|
||||
}
|
||||
|
||||
rc = nvioctlNvmap_FromID(g_nvgfx_fd_nvmap, tmpval, &tmpval);
|
||||
if (R_FAILED(rc)) break;
|
||||
|
||||
//The above gets a nvmap_handle, but normally it's the same value passed to nvioctlNvmap_GetID().
|
||||
|
||||
g_gfxprod_BufferInitData[0xa] = i;
|
||||
g_gfxprod_BufferInitData[0xe] = tmpval;
|
||||
g_gfxprod_BufferInitData[0x20] = tmpval;
|
||||
g_gfxprod_BufferInitData[0x21] = 0x3c0000*i;
|
||||
ptr64[0x170>>3] = svcGetSystemTick();
|
||||
rc = gfxproducerBufferInit(i, (u8*)g_gfxprod_BufferInitData);
|
||||
if (R_FAILED(rc)) break;
|
||||
}
|
||||
if (R_FAILED(rc)) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,17 +356,6 @@ Result nvgfxInitialize(void) {
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = nvOpen(&g_nvgfx_fd_nvhostctrl, "/dev/nvhost-ctrl");
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
do {
|
||||
rc = nvioctlNvhostCtrl_EventWait(g_nvgfx_fd_nvhostctrl, 0x42, 0x1ca7, 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);
|
||||
|
||||
//if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrl_EventSignal(g_nvgfx_fd_nvhostctrl, g_nvgfx_nvhostctrl_eventres);
|
||||
|
||||
//if (R_SUCCEEDED(rc)) rc = -1;
|
||||
|
||||
if (R_FAILED(rc)) {
|
||||
@ -382,3 +437,20 @@ void nvgfxExit(void) {
|
||||
g_nvgfxInitialized = 0;
|
||||
}
|
||||
|
||||
Result nvgfxEventInit(void) {
|
||||
Result rc=0;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
do {
|
||||
rc = nvioctlNvhostCtrl_EventWait(g_nvgfx_fd_nvhostctrl, 0x42, 0x1ca7, 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);
|
||||
|
||||
//if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrl_EventSignal(g_nvgfx_fd_nvhostctrl, g_nvgfx_nvhostctrl_eventres);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -264,6 +264,25 @@ Result nvioctlNvmap_Create(u32 fd, u32 size, u32 *nvmap_handle) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result nvioctlNvmap_FromID(u32 fd, u32 id, u32 *nvmap_handle) {
|
||||
Result rc=0;
|
||||
|
||||
struct {
|
||||
u32 id;//in
|
||||
u32 handle;//out
|
||||
} data;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.id = id;
|
||||
|
||||
rc = nvIoctl(fd, _IOWR(0x01, 0x03, data), &data);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
*nvmap_handle = data.handle;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result nvioctlNvmap_Alloc(u32 fd, u32 nvmap_handle, u32 heapmask, u32 flags, u32 align, u8 kind, void* addr) {
|
||||
struct {
|
||||
u32 handle;//in
|
||||
@ -286,6 +305,25 @@ Result nvioctlNvmap_Alloc(u32 fd, u32 nvmap_handle, u32 heapmask, u32 flags, u32
|
||||
return nvIoctl(fd, _IOWR(0x01, 0x04, data), &data);
|
||||
}
|
||||
|
||||
Result nvioctlNvmap_GetID(u32 fd, u32 nvmap_handle, u32 *id) {
|
||||
Result rc=0;
|
||||
|
||||
struct {
|
||||
u32 id;//out
|
||||
u32 handle;//in
|
||||
} data;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.handle = nvmap_handle;
|
||||
|
||||
rc = nvIoctl(fd, _IOWR(0x01, 0x0E, data), &data);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
*id = data.id;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result nvioctlChannel_SetNvmapFd(u32 fd, u32 nvmap_fd) {
|
||||
struct {
|
||||
u32 fd;//in
|
||||
|
@ -3,8 +3,12 @@
|
||||
|
||||
//This implements Android Parcel, hence names etc here are based on Android Parcel.cpp.
|
||||
|
||||
/*u8 parcel_reply_log[0x10000] = {0};
|
||||
size_t parcel_reply_log_size = 0;*/
|
||||
//#define PARCEL_LOGGING
|
||||
|
||||
#ifdef PARCEL_LOGGING
|
||||
u8 parcel_reply_log[0x10000] = {0};
|
||||
size_t parcel_reply_log_size = 0;
|
||||
#endif
|
||||
|
||||
void parcelInitializeContext(parcelContext *ctx) {
|
||||
memset(ctx, 0, sizeof(parcelContext));
|
||||
@ -44,12 +48,14 @@ Result parcelTransact(binderSession *session, u32 code, parcelContext *in_parcel
|
||||
memcpy(parcel_reply->ParcelData, &outparcel[outparcel32[1]], outparcel32[0]);
|
||||
parcel_reply->ParcelData_size = outparcel32[0];
|
||||
|
||||
/*if(parcel_reply_log_size + sizeof(inparcel) + outparcel_size <= sizeof(parcel_reply_log)) {
|
||||
#ifdef PARCEL_LOGGING
|
||||
if(parcel_reply_log_size + sizeof(inparcel) + outparcel_size <= sizeof(parcel_reply_log)) {
|
||||
memcpy(&parcel_reply_log[parcel_reply_log_size], inparcel, sizeof(inparcel));
|
||||
parcel_reply_log_size+= sizeof(inparcel);
|
||||
memcpy(&parcel_reply_log[parcel_reply_log_size], outparcel, outparcel_size);
|
||||
parcel_reply_log_size+= outparcel_size;
|
||||
}*/
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user