mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-28 07:42:55 +02:00
More refactoring, renamed graphicsproducer -> bufferproducer
This commit is contained in:
parent
7f2135754a
commit
806a75c841
@ -38,7 +38,7 @@ extern "C" {
|
||||
|
||||
#include <switch/gfx/gfx.h>
|
||||
#include <switch/gfx/parcel.h>
|
||||
#include <switch/gfx/gfxproducer.h>
|
||||
#include <switch/gfx/buffer_producer.h>
|
||||
#include <switch/gfx/ioctl.h>
|
||||
#include <switch/gfx/nvioctl.h>
|
||||
#include <switch/gfx/nvgfx.h>
|
||||
|
11
nx/include/switch/gfx/buffer_producer.h
Normal file
11
nx/include/switch/gfx/buffer_producer.h
Normal file
@ -0,0 +1,11 @@
|
||||
Result bufferProducerInitialize(binderSession *session);
|
||||
void bufferProducerExit();
|
||||
|
||||
Result bufferProducerRequestBuffer(s32 bufferIdx);
|
||||
Result bufferProducerDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage, s32 *buf);
|
||||
Result bufferProducerDetachBuffer(s32 slot);
|
||||
Result bufferProducerQueueBuffer(s32 buf, u8 input[0x5c]);
|
||||
Result bufferProducerQuery(s32 what, s32* value);
|
||||
Result bufferProducerConnect(s32 api, bool producerControlledByApp);
|
||||
Result bufferProducerDisconnect(s32 api);
|
||||
Result bufferProducerTegraBufferInit(s32 buf, u8 input[0x178]);
|
@ -1,11 +0,0 @@
|
||||
Result gfxproducerInitialize(binderSession *session);
|
||||
void gfxproducerExit();
|
||||
|
||||
Result gfxproducerRequestBuffer(s32 bufferIdx);
|
||||
Result gfxproducerDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage, s32 *buf);
|
||||
Result gfxproducerDetachBuffer(s32 slot);
|
||||
Result gfxproducerQueueBuffer(s32 buf, u8 input[0x5c]);
|
||||
Result gfxproducerQuery(s32 what, s32* value);
|
||||
Result gfxproducerConnect(s32 api, bool producerControlledByApp);
|
||||
Result gfxproducerDisconnect(s32 api);
|
||||
Result gfxproducerTegraBufferInit(s32 buf, u8 input[0x178]);
|
@ -9,20 +9,19 @@ typedef struct {
|
||||
|
||||
u8 *ParcelObjects;
|
||||
u32 ParcelObjectsSize;
|
||||
} parcelContext;
|
||||
} Parcel;
|
||||
|
||||
void parcelInitializeContext(parcelContext *ctx);
|
||||
Result parcelTransact(binderSession *session, u32 code, parcelContext *in_parcel, parcelContext *reply_parcel);
|
||||
void parcelInitialize(Parcel *ctx);
|
||||
Result parcelTransact(binderSession *session, u32 code, Parcel *in_parcel, Parcel *reply_parcel);
|
||||
|
||||
void* parcelWriteData(parcelContext *ctx, void* data, size_t data_size);
|
||||
void* parcelReadData(parcelContext *ctx, void* data, size_t data_size);
|
||||
void* parcelWriteData(Parcel *ctx, void* data, size_t data_size);
|
||||
void* parcelReadData(Parcel *ctx, void* data, size_t data_size);
|
||||
|
||||
void parcelWriteInt32(parcelContext *ctx, s32 val);
|
||||
void parcelWriteUInt32(parcelContext *ctx, u32 val);
|
||||
void parcelWriteString16(parcelContext *ctx, const char *str);
|
||||
void parcelWriteInt32(Parcel *ctx, s32 val);
|
||||
void parcelWriteUInt32(Parcel *ctx, u32 val);
|
||||
void parcelWriteString16(Parcel *ctx, const char *str);
|
||||
void parcelWriteInterfaceToken(Parcel *ctx, const char *interface);
|
||||
|
||||
void parcelWriteInterfaceToken(parcelContext *ctx, const char *interface);
|
||||
|
||||
s32 parcelReadInt32(parcelContext *ctx);
|
||||
u32 parcelReadUInt32(parcelContext *ctx);
|
||||
s32 parcelReadInt32(Parcel *ctx);
|
||||
u32 parcelReadUInt32(Parcel *ctx);
|
||||
|
||||
|
@ -30,4 +30,5 @@
|
||||
#define LIBNX_IOERROR 9
|
||||
#define LIBNX_BADINPUT 10
|
||||
#define LIBNX_BADREENT 11
|
||||
#define LIBNX_BUFFERPRODUCER_ERROR 12
|
||||
#define LIBNX_PARCEL_ERRBASE 100
|
||||
|
252
nx/source/gfx/buffer_producer.c
Normal file
252
nx/source/gfx/buffer_producer.c
Normal file
@ -0,0 +1,252 @@
|
||||
#include <string.h>
|
||||
#include <switch.h>
|
||||
|
||||
// This implements the version of Android IGraphicBufferProducer used by Switch.
|
||||
// Hence names/params etc here are based on Android IGraphicBufferProducer.cpp.
|
||||
|
||||
// Based on an old version of the enum from the above .cpp.
|
||||
// Unknown whether all of these are correct for Switch.
|
||||
enum {
|
||||
/* 0x1 */ REQUEST_BUFFER = BINDER_FIRST_CALL_TRANSACTION,
|
||||
/* 0x2 */ SET_BUFFER_COUNT,
|
||||
/* 0x3 */ DEQUEUE_BUFFER,
|
||||
/* 0x4 */ DETACH_BUFFER,
|
||||
/* 0x5 */ DETACH_NEXT_BUFFER,
|
||||
/* 0x6 */ ATTACH_BUFFER,
|
||||
/* 0x7 */ QUEUE_BUFFER,
|
||||
/* 0x8 */ CANCEL_BUFFER,
|
||||
/* 0x9 */ QUERY,
|
||||
/* 0xA */ CONNECT,
|
||||
/* 0xB */ DISCONNECT,
|
||||
/* 0xC */ SET_SIDEBAND_STREAM,
|
||||
/* 0xD */ ALLOCATE_BUFFERS,
|
||||
/* 0xE */ TEGRA_BUFFER_INIT, // Custom Switch-specific command - unofficial name.
|
||||
};
|
||||
|
||||
static char g_bufferProducer_InterfaceDescriptor[] = "android.gui.IGraphicBufferProducer";
|
||||
|
||||
static binderSession *g_bufferProducerBinderSession;
|
||||
|
||||
Result bufferProducerInitialize(binderSession *session)
|
||||
{
|
||||
g_bufferProducerBinderSession = session;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bufferProducerExit()
|
||||
{
|
||||
g_bufferProducerBinderSession = NULL;
|
||||
}
|
||||
|
||||
Result bufferProducerRequestBuffer(s32 bufferIdx)
|
||||
{
|
||||
Result rc;
|
||||
Parcel parcel, parcel_reply;
|
||||
|
||||
if (g_bufferProducerBinderSession == NULL)
|
||||
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, 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));
|
||||
}
|
||||
|
||||
int status = parcelReadInt32(&parcel_reply);
|
||||
|
||||
if (status != 0) {
|
||||
rc = MAKERESULT(MODULE_LIBNX, LIBNX_BUFFERPRODUCER_ERROR);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result bufferProducerDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage, s32 *buf)
|
||||
{
|
||||
Result rc;
|
||||
Parcel parcel, parcel_reply;
|
||||
|
||||
if (g_bufferProducerBinderSession == NULL)
|
||||
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
|
||||
|
||||
parcelWriteInt32(&parcel, async);
|
||||
parcelWriteUInt32(&parcel, width);
|
||||
parcelWriteUInt32(&parcel, height);
|
||||
parcelWriteInt32(&parcel, format);
|
||||
parcelWriteUInt32(&parcel, usage);
|
||||
|
||||
rc = parcelTransact(g_bufferProducerBinderSession, DEQUEUE_BUFFER, &parcel, &parcel_reply);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
// TODO: parse reply
|
||||
*buf = parcelReadInt32(&parcel_reply);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result bufferProducerDetachBuffer(s32 slot)
|
||||
{
|
||||
Result rc;
|
||||
Parcel parcel, parcel_reply;
|
||||
|
||||
if (g_bufferProducerBinderSession == NULL)
|
||||
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, slot);
|
||||
|
||||
rc = parcelTransact(g_bufferProducerBinderSession, DETACH_BUFFER, &parcel, &parcel_reply);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
//TODO: parse reply
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result bufferProducerQueueBuffer(s32 buf, u8 input[0x5c])
|
||||
{
|
||||
Result rc;
|
||||
Parcel parcel, parcel_reply;
|
||||
|
||||
if (g_bufferProducerBinderSession == NULL)
|
||||
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, buf);
|
||||
parcelWriteData(&parcel, input, 0x5c);
|
||||
|
||||
rc = parcelTransact(g_bufferProducerBinderSession, QUEUE_BUFFER, &parcel, &parcel_reply);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
//TODO: parse reply
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result bufferProducerQuery(s32 what, s32* value)
|
||||
{
|
||||
Result rc;
|
||||
Parcel parcel, parcel_reply;
|
||||
|
||||
if (g_bufferProducerBinderSession == NULL)
|
||||
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, what);
|
||||
|
||||
rc = parcelTransact(g_bufferProducerBinderSession, QUERY, &parcel, &parcel_reply);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
*value = parcelReadInt32(&parcel_reply);
|
||||
|
||||
int result = parcelReadInt32(&parcel_reply);
|
||||
if (result != 0)
|
||||
rc = MAKERESULT(MODULE_LIBNX, LIBNX_BUFFERPRODUCER_ERROR);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result bufferProducerConnect(s32 api, bool producerControlledByApp)
|
||||
{
|
||||
Result rc;
|
||||
Parcel parcel, parcel_reply;
|
||||
|
||||
if (g_bufferProducerBinderSession == NULL)
|
||||
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
|
||||
|
||||
// Hard-code this as if listener==NULL, since that's not known to be used officially.
|
||||
parcelWriteInt32(&parcel, 0);
|
||||
parcelWriteInt32(&parcel, api);
|
||||
parcelWriteInt32(&parcel, producerControlledByApp);
|
||||
|
||||
rc = parcelTransact(g_bufferProducerBinderSession, CONNECT, &parcel, &parcel_reply);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
//TODO: parse reply (contains 32bit width and height)
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result bufferProducerDisconnect(s32 api)
|
||||
{
|
||||
Result rc;
|
||||
Parcel parcel, parcel_reply;
|
||||
|
||||
if (g_bufferProducerBinderSession == NULL)
|
||||
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, api);
|
||||
|
||||
rc = parcelTransact(g_bufferProducerBinderSession, DISCONNECT, &parcel, &parcel_reply);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
//TODO: parse reply
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result bufferProducerTegraBufferInit(s32 buf, u8 input[0x178])
|
||||
{
|
||||
Result rc;
|
||||
Parcel parcel, parcel_reply;
|
||||
|
||||
if (g_bufferProducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, buf);
|
||||
parcelWriteData(&parcel, input, 0x178);
|
||||
|
||||
rc = parcelTransact(g_bufferProducerBinderSession, TEGRA_BUFFER_INIT, &parcel, &parcel_reply);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
// TODO: parse reply
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ static Result _gfxDequeueBuffer() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = gfxproducerDequeueBuffer(/*1*/0, 1280, 720, 0, 0x300, &g_gfxCurrentProducerBuffer);
|
||||
rc = bufferProducerDequeueBuffer(/*1*/0, 1280, 720, 0, 0x300, &g_gfxCurrentProducerBuffer);
|
||||
|
||||
if (R_SUCCEEDED(rc)) g_gfxCurrentBuffer = (g_gfxCurrentBuffer + 1) & (g_nvgfx_totalframebufs-1);
|
||||
|
||||
@ -72,7 +72,7 @@ static Result _gfxQueueBuffer(s32 buf) {
|
||||
|
||||
ptr64[1] = svcGetSystemTick();//Unknown what is actually used for timestamp, but shouldn't(?) matter.
|
||||
|
||||
rc = gfxproducerQueueBuffer(buf, (u8*)g_gfxQueueBufferData);
|
||||
rc = bufferProducerQueueBuffer(buf, (u8*)g_gfxQueueBufferData);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
/*if(buf==0) {
|
||||
@ -121,9 +121,9 @@ 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 = gfxproducerInitialize(&g_gfxBinderSession);
|
||||
if (R_SUCCEEDED(rc)) rc = bufferProducerInitialize(&g_gfxBinderSession);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = gfxproducerConnect(2, 0);
|
||||
if (R_SUCCEEDED(rc)) rc = bufferProducerConnect(2, 0);
|
||||
|
||||
if (R_SUCCEEDED(rc)) g_gfx_ProducerConnected = 1;
|
||||
|
||||
@ -136,7 +136,7 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L
|
||||
rc = _gfxDequeueBuffer();
|
||||
if (R_FAILED(rc)) break;
|
||||
|
||||
rc = gfxproducerRequestBuffer(g_gfxCurrentProducerBuffer);
|
||||
rc = bufferProducerRequestBuffer(g_gfxCurrentProducerBuffer);
|
||||
if (R_FAILED(rc)) break;
|
||||
|
||||
g_gfx_ProducerSlotsRequested[i] = 1;
|
||||
@ -162,12 +162,12 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L
|
||||
if (R_FAILED(rc)) {
|
||||
_gfxQueueBuffer(g_gfxCurrentProducerBuffer);
|
||||
for(i=0; i<2; i++) {
|
||||
if (g_gfx_ProducerSlotsRequested[i]) gfxproducerDetachBuffer(i);
|
||||
if (g_gfx_ProducerSlotsRequested[i]) bufferProducerDetachBuffer(i);
|
||||
}
|
||||
if (g_gfx_ProducerConnected) gfxproducerDisconnect(2);
|
||||
if (g_gfx_ProducerConnected) bufferProducerDisconnect(2);
|
||||
|
||||
nvgfxExit();
|
||||
gfxproducerExit();
|
||||
bufferProducerExit();
|
||||
binderExitSession(&g_gfxBinderSession);
|
||||
nvExit();
|
||||
|
||||
@ -223,13 +223,13 @@ void gfxExit(void) {
|
||||
|
||||
_gfxQueueBuffer(g_gfxCurrentProducerBuffer);
|
||||
for(i=0; i<2; i++) {
|
||||
if (g_gfx_ProducerSlotsRequested[i]) gfxproducerDetachBuffer(i);
|
||||
if (g_gfx_ProducerSlotsRequested[i]) bufferProducerDetachBuffer(i);
|
||||
}
|
||||
if (g_gfx_ProducerConnected) gfxproducerDisconnect(2);
|
||||
if (g_gfx_ProducerConnected) bufferProducerDisconnect(2);
|
||||
|
||||
nvgfxExit();
|
||||
|
||||
gfxproducerExit();
|
||||
bufferProducerExit();
|
||||
binderExitSession(&g_gfxBinderSession);
|
||||
|
||||
nvExit();
|
||||
|
@ -1,218 +0,0 @@
|
||||
#include <string.h>
|
||||
#include <switch.h>
|
||||
|
||||
//This implements the version of Android IGraphicBufferProducer used by Switch, hence names/params etc here are based on Android IGraphicBufferProducer.cpp.
|
||||
|
||||
//Based on an old version of the enum from the above .cpp.
|
||||
//Unknown whether all of these are correct for Switch.
|
||||
enum {
|
||||
REQUEST_BUFFER = BINDER_FIRST_CALL_TRANSACTION, //0x1
|
||||
SET_BUFFER_COUNT, //0x2
|
||||
DEQUEUE_BUFFER, //0x3
|
||||
DETACH_BUFFER, //0x4
|
||||
DETACH_NEXT_BUFFER, //0x5
|
||||
ATTACH_BUFFER, //0x6
|
||||
QUEUE_BUFFER, //0x7
|
||||
CANCEL_BUFFER, //0x8
|
||||
QUERY, //0x9
|
||||
CONNECT, //0xA
|
||||
DISCONNECT, //0xB
|
||||
SET_SIDEBAND_STREAM, //0xC
|
||||
ALLOCATE_BUFFERS, //0xD
|
||||
TEGRA_BUFFER_INIT, //0xE (Custom Switch-specific command - unofficial name)
|
||||
};
|
||||
|
||||
static char g_gfxproducer_InterfaceDescriptor[] = "android.gui.IGraphicBufferProducer";
|
||||
|
||||
static binderSession *g_gfxproducerBinderSession;
|
||||
|
||||
Result gfxproducerInitialize(binderSession *session) {
|
||||
g_gfxproducerBinderSession = session;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gfxproducerExit() {
|
||||
g_gfxproducerBinderSession = NULL;
|
||||
}
|
||||
|
||||
Result gfxproducerRequestBuffer(s32 bufferIdx) {
|
||||
Result rc;
|
||||
parcelContext parcel, parcel_reply;
|
||||
|
||||
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitializeContext(&parcel);
|
||||
parcelInitializeContext(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_gfxproducer_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, bufferIdx);
|
||||
|
||||
rc = parcelTransact(g_gfxproducerBinderSession, REQUEST_BUFFER, &parcel, &parcel_reply);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
//TODO: parse reply
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result gfxproducerDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage, s32 *buf) {
|
||||
Result rc;
|
||||
parcelContext parcel, parcel_reply;
|
||||
|
||||
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitializeContext(&parcel);
|
||||
parcelInitializeContext(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_gfxproducer_InterfaceDescriptor);
|
||||
|
||||
parcelWriteInt32(&parcel, async);
|
||||
parcelWriteUInt32(&parcel, width);
|
||||
parcelWriteUInt32(&parcel, height);
|
||||
parcelWriteInt32(&parcel, format);
|
||||
parcelWriteUInt32(&parcel, usage);
|
||||
|
||||
rc = parcelTransact(g_gfxproducerBinderSession, DEQUEUE_BUFFER, &parcel, &parcel_reply);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
//TODO: parse reply
|
||||
|
||||
*buf = parcelReadInt32(&parcel_reply);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result gfxproducerDetachBuffer(s32 slot) {
|
||||
Result rc;
|
||||
parcelContext parcel, parcel_reply;
|
||||
|
||||
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitializeContext(&parcel);
|
||||
parcelInitializeContext(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_gfxproducer_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, slot);
|
||||
|
||||
rc = parcelTransact(g_gfxproducerBinderSession, DETACH_BUFFER, &parcel, &parcel_reply);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
//TODO: parse reply
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result gfxproducerQueueBuffer(s32 buf, u8 input[0x5c]) {
|
||||
Result rc;
|
||||
parcelContext parcel, parcel_reply;
|
||||
|
||||
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitializeContext(&parcel);
|
||||
parcelInitializeContext(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_gfxproducer_InterfaceDescriptor);
|
||||
|
||||
parcelWriteInt32(&parcel, buf);
|
||||
parcelWriteData(&parcel, input, 0x5c);
|
||||
|
||||
rc = parcelTransact(g_gfxproducerBinderSession, QUEUE_BUFFER, &parcel, &parcel_reply);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
//TODO: parse reply
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result gfxproducerQuery(s32 what, s32* value) {
|
||||
Result rc;
|
||||
parcelContext parcel, parcel_reply;
|
||||
|
||||
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitializeContext(&parcel);
|
||||
parcelInitializeContext(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_gfxproducer_InterfaceDescriptor);
|
||||
|
||||
parcelWriteInt32(&parcel, what);
|
||||
|
||||
rc = parcelTransact(g_gfxproducerBinderSession, QUERY, &parcel, &parcel_reply);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
*value = parcelReadInt32(&parcel_reply);
|
||||
rc = parcelReadInt32(&parcel_reply);
|
||||
if (rc) rc = MAKERESULT(MODULE_LIBNX, LIBNX_PARCEL_ERRBASE);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result gfxproducerConnect(s32 api, bool producerControlledByApp) {
|
||||
Result rc;
|
||||
parcelContext parcel, parcel_reply;
|
||||
|
||||
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitializeContext(&parcel);
|
||||
parcelInitializeContext(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_gfxproducer_InterfaceDescriptor);
|
||||
|
||||
//Hard-code this as if listener==NULL, since that's not known to be used officially.
|
||||
parcelWriteInt32(&parcel, 0);
|
||||
|
||||
parcelWriteInt32(&parcel, api);
|
||||
parcelWriteInt32(&parcel, producerControlledByApp);
|
||||
|
||||
rc = parcelTransact(g_gfxproducerBinderSession, CONNECT, &parcel, &parcel_reply);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
//TODO: parse reply (contains 32bit width and height)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result gfxproducerDisconnect(s32 api) {
|
||||
Result rc;
|
||||
parcelContext parcel, parcel_reply;
|
||||
|
||||
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitializeContext(&parcel);
|
||||
parcelInitializeContext(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_gfxproducer_InterfaceDescriptor);
|
||||
|
||||
parcelWriteInt32(&parcel, api);
|
||||
|
||||
rc = parcelTransact(g_gfxproducerBinderSession, DISCONNECT, &parcel, &parcel_reply);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
//TODO: parse reply
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result gfxproducerTegraBufferInit(s32 buf, u8 input[0x178]) {
|
||||
Result rc;
|
||||
parcelContext parcel, parcel_reply;
|
||||
|
||||
if (g_gfxproducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
|
||||
|
||||
parcelInitializeContext(&parcel);
|
||||
parcelInitializeContext(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_gfxproducer_InterfaceDescriptor);
|
||||
|
||||
parcelWriteInt32(&parcel, buf);
|
||||
parcelWriteData(&parcel, input, 0x178);
|
||||
|
||||
rc = parcelTransact(g_gfxproducerBinderSession, TEGRA_BUFFER_INIT, &parcel, &parcel_reply);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
//TODO: parse reply
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ Result nvgfxInitialize(void) {
|
||||
if (R_FAILED(rc)) break;
|
||||
|
||||
if(pos==1) {
|
||||
rc = gfxproducerQuery(2, &tmp);//"NATIVE_WINDOW_FORMAT"
|
||||
rc = bufferProducerQuery(2, &tmp);//"NATIVE_WINDOW_FORMAT"
|
||||
if (R_FAILED(rc)) break;
|
||||
|
||||
for(i=0; i<2; i++) {
|
||||
@ -309,7 +309,7 @@ Result nvgfxInitialize(void) {
|
||||
g_gfxprod_BufferInitData[0x20] = tmpval;
|
||||
g_gfxprod_BufferInitData[0x21] = g_nvgfx_singleframebuf_size*i;
|
||||
ptr64[0x170>>3] = svcGetSystemTick();
|
||||
rc = gfxproducerTegraBufferInit(i, (u8*)g_gfxprod_BufferInitData);
|
||||
rc = bufferProducerTegraBufferInit(i, (u8*)g_gfxprod_BufferInitData);
|
||||
if (R_FAILED(rc)) break;
|
||||
}
|
||||
if (R_FAILED(rc)) break;
|
||||
|
@ -10,12 +10,12 @@ u8 parcel_reply_log[0x10000] = {0};
|
||||
size_t parcel_reply_log_size = 0;
|
||||
#endif
|
||||
|
||||
void parcelInitializeContext(parcelContext *ctx) {
|
||||
memset(ctx, 0, sizeof(parcelContext));
|
||||
void parcelInitialize(Parcel *ctx) {
|
||||
memset(ctx, 0, sizeof(Parcel));
|
||||
ctx->capacity = sizeof(ctx->payload);
|
||||
}
|
||||
|
||||
Result parcelTransact(binderSession *session, u32 code, parcelContext *in_parcel, parcelContext *parcel_reply) {
|
||||
Result parcelTransact(binderSession *session, u32 code, Parcel *in_parcel, Parcel *parcel_reply) {
|
||||
Result rc=0;
|
||||
u8 inparcel[0x400];
|
||||
u8 outparcel[0x400];
|
||||
@ -65,7 +65,7 @@ Result parcelTransact(binderSession *session, u32 code, parcelContext *in_parcel
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* parcelWriteData(parcelContext *ctx, void* data, size_t data_size) {
|
||||
void* parcelWriteData(Parcel *ctx, void* data, size_t data_size) {
|
||||
void* ptr = &ctx->payload[ctx->size];
|
||||
|
||||
if(data_size & BIT(31))
|
||||
@ -84,7 +84,7 @@ void* parcelWriteData(parcelContext *ctx, void* data, size_t data_size) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* parcelReadData(parcelContext *ctx, void* data, size_t data_size) {
|
||||
void* parcelReadData(Parcel *ctx, void* data, size_t data_size) {
|
||||
void* ptr = ctx->payload;
|
||||
|
||||
if(data_size & BIT(31))
|
||||
@ -103,7 +103,7 @@ void* parcelReadData(parcelContext *ctx, void* data, size_t data_size) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void parcelWriteString16(parcelContext *ctx, const char *str) {
|
||||
void parcelWriteString16(Parcel *ctx, const char *str) {
|
||||
u32 pos, len;
|
||||
u16 *ptr;
|
||||
|
||||
@ -120,27 +120,27 @@ void parcelWriteString16(parcelContext *ctx, const char *str) {
|
||||
}
|
||||
}
|
||||
|
||||
s32 parcelReadInt32(parcelContext *ctx) {
|
||||
s32 parcelReadInt32(Parcel *ctx) {
|
||||
s32 val = 0;
|
||||
parcelReadData(ctx, &val, sizeof(val));
|
||||
return val;
|
||||
}
|
||||
|
||||
u32 parcelReadUInt32(parcelContext *ctx) {
|
||||
u32 parcelReadUInt32(Parcel *ctx) {
|
||||
u32 val = 0;
|
||||
parcelReadData(ctx, &val, sizeof(val));
|
||||
return val;
|
||||
}
|
||||
|
||||
void parcelWriteInt32(parcelContext *ctx, s32 val) {
|
||||
void parcelWriteInt32(Parcel *ctx, s32 val) {
|
||||
parcelWriteData(ctx, &val, sizeof(val));
|
||||
}
|
||||
|
||||
void parcelWriteUInt32(parcelContext *ctx, u32 val) {
|
||||
void parcelWriteUInt32(Parcel *ctx, u32 val) {
|
||||
parcelWriteData(ctx, &val, sizeof(val));
|
||||
}
|
||||
|
||||
void parcelWriteInterfaceToken(parcelContext *ctx, const char *interface) {
|
||||
void parcelWriteInterfaceToken(Parcel *ctx, const char *interface) {
|
||||
parcelWriteInt32(ctx, 0x100);
|
||||
parcelWriteString16(ctx, interface);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user