Added bufferProducerGraphicBuffer struct. Parse the bufferProducerRequestBuffer parcel reply properly. Renamed bufferProducerTegraBufferInit to bufferProducerGraphicBufferInit + renamed the enum for it, and handle input/output for it properly. Properly return rc in bufferProducerGraphicBufferInit().

This commit is contained in:
yellows8 2017-12-19 12:13:37 -05:00
parent c0780f5267
commit dd4a9bbca6
4 changed files with 37 additions and 23 deletions

View File

@ -25,6 +25,10 @@ typedef struct {
u32 numPendingBuffers;
} PACKED bufferProducerQueueBufferOutput;
typedef struct {
u32 unk[0x16c>>2];
} PACKED bufferProducerGraphicBuffer;
//From Android window.h.
/* attributes queriable with query() */
enum {
@ -49,11 +53,11 @@ enum {
Result bufferProducerInitialize(binderSession *session);
void bufferProducerExit();
Result bufferProducerRequestBuffer(s32 bufferIdx);
Result bufferProducerRequestBuffer(s32 bufferIdx, bufferProducerGraphicBuffer *buf);
Result bufferProducerDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage, s32 *buf, bufferProducerFence *fence);
Result bufferProducerDetachBuffer(s32 slot);
Result bufferProducerQueueBuffer(s32 buf, bufferProducerQueueBufferInput *input, bufferProducerQueueBufferOutput *output);
Result bufferProducerQuery(s32 what, s32* value);
Result bufferProducerConnect(s32 api, bool producerControlledByApp, bufferProducerQueueBufferOutput *output);
Result bufferProducerDisconnect(s32 api);
Result bufferProducerTegraBufferInit(s32 buf, u8 input[0x178]);
Result bufferProducerGraphicBufferInit(s32 buf, bufferProducerGraphicBuffer *input);

View File

@ -20,7 +20,7 @@ enum {
/* 0xB */ DISCONNECT,
/* 0xC */ SET_SIDEBAND_STREAM,
/* 0xD */ ALLOCATE_BUFFERS,
/* 0xE */ TEGRA_BUFFER_INIT, // Custom Switch-specific command - unofficial name.
/* 0xE */ GRAPHIC_BUFFER_INIT, // Custom Switch-specific command - unofficial name.
};
static char g_bufferProducer_InterfaceDescriptor[] = "android.gui.IGraphicBufferProducer";
@ -38,7 +38,7 @@ void bufferProducerExit()
g_bufferProducerBinderSession = NULL;
}
Result bufferProducerRequestBuffer(s32 bufferIdx)
Result bufferProducerRequestBuffer(s32 bufferIdx, bufferProducerGraphicBuffer *buf)
{
Result rc;
Parcel parcel, parcel_reply;
@ -55,12 +55,15 @@ Result bufferProducerRequestBuffer(s32 bufferIdx)
rc = parcelTransact(g_bufferProducerBinderSession, REQUEST_BUFFER, &parcel, &parcel_reply);
if (R_SUCCEEDED(rc)) {
/*
int nonNull = parcelReadInt32(&parcel_reply);
if (nonNull != 0) {
// Fixme
fatalSimple(222 | (100 << 9));
size_t tmpsize=0;
void* tmp_ptr;
tmp_ptr = parcelReadFlattenedObject(&parcel_reply, &tmpsize);
if (tmp_ptr==NULL || tmpsize!=sizeof(bufferProducerGraphicBuffer)) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
if (buf) memcpy(buf, tmp_ptr, sizeof(bufferProducerGraphicBuffer));
}
int status = parcelReadInt32(&parcel_reply);
@ -68,7 +71,6 @@ Result bufferProducerRequestBuffer(s32 bufferIdx)
if (status != 0) {
rc = MAKERESULT(MODULE_LIBNX, LIBNX_BUFFERPRODUCER_ERROR);
}
*/
}
return rc;
@ -247,10 +249,11 @@ Result bufferProducerDisconnect(s32 api)
return rc;
}
Result bufferProducerTegraBufferInit(s32 buf, u8 input[0x178])
Result bufferProducerGraphicBufferInit(s32 buf, bufferProducerGraphicBuffer *input)
{
Result rc;
Parcel parcel, parcel_reply;
bool flag = 0;
if (g_bufferProducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
@ -259,14 +262,19 @@ Result bufferProducerTegraBufferInit(s32 buf, u8 input[0x178])
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
parcelWriteInt32(&parcel, buf);
parcelWriteData(&parcel, input, 0x178);
rc = parcelTransact(g_bufferProducerBinderSession, TEGRA_BUFFER_INIT, &parcel, &parcel_reply);
if (input!=NULL) flag = 1;
parcelWriteInt32(&parcel, flag);
if (flag) parcelWriteFlattenedObject(&parcel, input, sizeof(bufferProducerGraphicBuffer));
rc = parcelTransact(g_bufferProducerBinderSession, GRAPHIC_BUFFER_INIT, &parcel, &parcel_reply);
if (R_SUCCEEDED(rc)) {
// TODO: parse reply
int result = parcelReadInt32(&parcel_reply);
if (result != 0)
rc = MAKERESULT(MODULE_LIBNX, LIBNX_BUFFERPRODUCER_ERROR);
}
return 0;
return rc;
}

View File

@ -162,7 +162,7 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L
rc = _gfxDequeueBuffer();
if (R_FAILED(rc)) break;
rc = bufferProducerRequestBuffer(g_gfxCurrentProducerBuffer);
rc = bufferProducerRequestBuffer(g_gfxCurrentProducerBuffer, NULL);
if (R_FAILED(rc)) break;
g_gfx_ProducerSlotsRequested[i] = 1;

View File

@ -47,8 +47,9 @@ static u64 nvmap_obj6_mapbuffer_xdb_offset;
static u64 g_nvgfx_gpfifo_pos = 0;
//Some of this struct is based on tegra_dc_ext_flip_windowattr.
static u32 g_gfxprod_BufferInitData[0x178>>2] = {
0x1, 0x16c, 0x0,
//TODO: How much of this struct do official apps really set? Most of it seems to be used as-is from the bufferProducerRequestBuffer() output.
static bufferProducerGraphicBuffer g_gfxprod_BufferInitData = {
.unk = {
0x47424652,
1280, 720,
1280,
@ -79,6 +80,7 @@ static u32 g_gfxprod_BufferInitData[0x178>>2] = {
0x0, 0x0, 0x0, 0x0,
0x0,
0x0, 0x0 //Unknown, some timestamp perhaps?
}
};
Result nvmapobjInitialize(nvmapobj *obj, size_t size) {
@ -132,7 +134,7 @@ Result nvgfxInitialize(void) {
u32 pos=0, i=0;
s32 tmp=0;
u32 tmpval=0;
u64 *ptr64 = (u64*)g_gfxprod_BufferInitData;
u64 *ptr64 = (u64*)g_gfxprod_BufferInitData.unk;
if(g_nvgfxInitialized)return 0;
u32 framebuf_nvmap_handle = 0;//Special handle ID for framebuf/windowbuf.
@ -311,12 +313,12 @@ Result nvgfxInitialize(void) {
//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] = g_nvgfx_singleframebuf_size*i;
ptr64[0x170>>3] = svcGetSystemTick();
rc = bufferProducerTegraBufferInit(i, (u8*)g_gfxprod_BufferInitData);
g_gfxprod_BufferInitData.unk[0x7] = i;
g_gfxprod_BufferInitData.unk[0xb] = tmpval;
g_gfxprod_BufferInitData.unk[0x1d] = tmpval;
g_gfxprod_BufferInitData.unk[0x1e] = g_nvgfx_singleframebuf_size*i;
ptr64[0x164>>3] = svcGetSystemTick();
rc = bufferProducerGraphicBufferInit(i, &g_gfxprod_BufferInitData);
if (R_FAILED(rc)) break;
}
if (R_FAILED(rc)) break;