diff --git a/gfx/gl.c b/gfx/gl.c index 897f21e37b..c5949b515c 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -239,6 +239,10 @@ static inline bool load_gl_proc_win32(gl_t *gl) #define pglUnmapBuffer glUnmapBuffer #endif +#ifdef __APPLE__ +#define GL_RGBA32F GL_RGBA32F_ARB +#endif + ////////////////// Shaders #ifdef HAVE_OPENGLES2 diff --git a/ios/RetroArch/input/BTStack/btpad_ps3.c b/ios/RetroArch/input/BTStack/btpad_ps3.c new file mode 100644 index 0000000000..a6f444dcbd --- /dev/null +++ b/ios/RetroArch/input/BTStack/btpad_ps3.c @@ -0,0 +1,185 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include +#include + +#include "boolean.h" +#include "../../rarch_wrapper.h" + +#include "btdynamic.h" +#include "btpad.h" + +enum btpad_ps3_state { BTPAD_PS3_INITIALIZING, BTPAD_PS3_PENDING, BTPAD_PS3_WANT_NAME, BTPAD_PS3_CONNECTED }; + +struct btpad_ps3_data +{ + enum btpad_ps3_state state; + + uint8_t data[512]; + + bool have_address; + bd_addr_t address; + uint32_t handle; + uint32_t channels[2]; +}; + +static void* btpad_ps3_connect() +{ + struct btpad_ps3_data* device = malloc(sizeof(struct btpad_ps3_data)); + memset(device, 0, sizeof(*device)); + + ios_add_log_message("BTstack PS3: Registering HID INTERRUPT service"); + bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_INTERRUPT, 672); + device->state = BTPAD_PS3_INITIALIZING; + + return device; +} + +static void btpad_ps3_disconnect(struct btpad_ps3_data* device) +{ + ios_add_log_message("BTstack PS3: Disconnecting."); + + bt_send_cmd_ptr(hci_disconnect_ptr, device->handle, 0x15); + free(device); +} + +static void btpad_ps3_setleds(struct btpad_ps3_data* device, unsigned leds) +{ + static uint8_t report_buffer[] = { + 0x52, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + report_buffer[11] = (leds & 0xF) << 1; + bt_send_l2cap_ptr(device->channels[0], report_buffer, sizeof(report_buffer)); +} + +static uint32_t btpad_ps3_get_buttons(struct btpad_ps3_data* device) +{ + return (device->state == BTPAD_PS3_CONNECTED) ? device->data[3] | (device->data[4] << 8) : 0; +} + +static void btpad_ps3_packet_handler(struct btpad_ps3_data* device, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) +{ + if (packet_type == HCI_EVENT_PACKET) + { + if (device->state == BTPAD_PS3_INITIALIZING) + { + if (packet[0] == L2CAP_EVENT_SERVICE_REGISTERED) + { + uint32_t psm = READ_BT_16(packet, 3); + if (psm == PSM_HID_INTERRUPT) + { + ios_add_log_message("BTstack PS3: HID INTERRUPT service registered"); + ios_add_log_message("BTstack PS3: Registering HID CONTROL service"); + bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_CONTROL, 672); + } + else if(psm == PSM_HID_CONTROL) + { + ios_add_log_message("BTstack PS3: HID CONTROL service registered"); + ios_add_log_message("BTstack PS3: Waiting for connection"); + device->state = BTPAD_PS3_PENDING; + } + } + } + else if(device->state == BTPAD_PS3_PENDING) + { + if (packet[0] == L2CAP_EVENT_INCOMING_CONNECTION) + { + const uint32_t psm = READ_BT_16(packet, 10); + const unsigned interrupt = (psm == PSM_HID_INTERRUPT) ? 1 : 0; + + ios_add_log_message("BTstack PS3: Incoming L2CAP connection for PSM: %02X", psm); + + bd_addr_t address; + bt_flip_addr_ptr(address, &packet[2]); + + if (!device->have_address || BD_ADDR_CMP(device->address, address) == 0) + { + device->have_address = true; + + bt_flip_addr_ptr(device->address, &packet[2]); + device->handle = READ_BT_16(packet, 8); + device->channels[interrupt] = READ_BT_16(packet, 12); + + bt_send_cmd_ptr(l2cap_accept_connection_ptr, device->channels[interrupt]); + ios_add_log_message("BTstack PS3: Connection accepted"); + + if (device->channels[0] && device->channels[1]) + { + ios_add_log_message("BTstack PS3: Got both channels, requesting name"); + bt_send_cmd_ptr(hci_remote_name_request_ptr, device->address, 0, 0, 0); + device->state = BTPAD_PS3_WANT_NAME; + } + } + else + ios_add_log_message("BTstack PS3: Connection unexpected; ignoring"); + } + } + else if(device->state == BTPAD_PS3_WANT_NAME) + { + if (packet[0] == HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE) + { + bd_addr_t event_addr; + bt_flip_addr_ptr(event_addr, &packet[3]); + + if (BD_ADDR_CMP(event_addr, device->address) == 0) + { + if (strncmp((char*)&packet[9], "PLAYSTATION(R)3 Controller", 26) == 0) + { + ios_add_log_message("BTstack PS3: Got 'PLAYSTATION(R)3 Controller'; Sending startup packets"); + + // Special packet to tell PS3 controller to send reports + uint8_t data[] = {0x53, 0xF4, 0x42, 0x03, 0x00, 0x00}; + bt_send_l2cap_ptr(device->channels[0], data, 6); + + btpad_ps3_setleds(device, 1); + + device->state = BTPAD_PS3_CONNECTED; + } + else + { + ios_add_log_message("BTstack PS3: Got %200s; Will keep looking", (char*)&packet[9]); + device->have_address = 0; + device->handle = 0; + device->channels[0] = 0; + device->channels[1] = 0; + device->state = BTPAD_PS3_PENDING; + } + } + } + } + } + else if (packet_type == L2CAP_DATA_PACKET && packet[0] == 0xA1) + memcpy(device->data, packet, size); +} + +struct btpad_interface btpad_ps3 = +{ + (void*)&btpad_ps3_connect, + (void*)&btpad_ps3_disconnect, + (void*)&btpad_ps3_setleds, + (void*)&btpad_ps3_get_buttons, + (void*)&btpad_ps3_packet_handler +}; diff --git a/ios/RetroArch/input/BTStack/btpad_wii.c b/ios/RetroArch/input/BTStack/btpad_wii.c new file mode 100644 index 0000000000..38ad670445 --- /dev/null +++ b/ios/RetroArch/input/BTStack/btpad_wii.c @@ -0,0 +1,245 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2013 - Jason Fetters + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include +#include + +#include "boolean.h" +#include "../../rarch_wrapper.h" + +#include "btdynamic.h" +#include "btpad.h" +#include "wiimote.h" + +enum btpad_wii_state { BTPAD_WII_WAITING, BTPAD_WII_PENDING, BTPAD_WII_WANT_NAME, BTPAD_WII_CONNECTING, BTPAD_WII_CONNECTED }; + +struct btpad_wii_data +{ + enum btpad_wii_state state; + struct wiimote_t wiimote; + + bd_addr_t address; + uint32_t page_scan_repetition_mode; + uint32_t class; + uint32_t clock_offset; + +}; + +static void* btpad_wii_connect() +{ + struct btpad_wii_data* device = malloc(sizeof(struct btpad_wii_data)); + memset(device, 0, sizeof(struct btpad_wii_data)); + + ios_add_log_message("BTstack Wii: Waiting for connection"); + bt_send_cmd_ptr(hci_inquiry_ptr, HCI_INQUIRY_LAP, 3, 0); + + device->state = BTPAD_WII_WAITING; + + return device; +} + +static void btpad_wii_disconnect(struct btpad_wii_data* device) +{ + ios_add_log_message("BTstack Wii: Disconnecting."); + + bt_send_cmd_ptr(hci_disconnect_ptr, device->wiimote.wiiMoteConHandle, 0x15); + free(device); +} + +static void btpad_wii_setleds(struct btpad_wii_data* device, unsigned leds) +{ +} + +static uint32_t btpad_wii_get_buttons(struct btpad_wii_data* device) +{ + return (device->state == BTPAD_WII_CONNECTED) ? device->wiimote.btns | (device->wiimote.exp.classic.btns << 16) : 0; +} + +static void btpad_wii_packet_handler(struct btpad_wii_data* device, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) +{ + if (packet_type == HCI_EVENT_PACKET && packet[0] == HCI_EVENT_PIN_CODE_REQUEST) + { + ios_add_log_message("BTstack Wii: Sending PIN"); + + bd_addr_t event_addr; + bt_flip_addr_ptr(event_addr, &packet[2]); + bt_send_cmd_ptr(hci_pin_code_request_reply_ptr, event_addr, 6, &packet[2]); + } + + if (packet_type == HCI_EVENT_PACKET) + { + if (device->state == BTPAD_WII_WAITING) + { + switch (packet[0]) + { + case HCI_EVENT_INQUIRY_RESULT: + { + if (packet[2]) + { + ios_add_log_message("BTstack Wii: Inquiry found device"); + device->state = BTPAD_WII_PENDING; + + bt_flip_addr_ptr(device->address, &packet[3]); + device->page_scan_repetition_mode = packet [3 + packet[2] * (6)]; + device->class = READ_BT_24(packet, 3 + packet[2] * (6+1+1+1)); + device->clock_offset = READ_BT_16(packet, 3 + packet[2] * (6+1+1+1+3)) & 0x7fff; + } + + break; + } + + case HCI_EVENT_INQUIRY_COMPLETE: + { + bt_send_cmd_ptr(hci_inquiry_ptr, HCI_INQUIRY_LAP, 3, 0); + break; + } + } + } + else if(device->state == BTPAD_WII_PENDING) + { + if (packet[0] == HCI_EVENT_INQUIRY_COMPLETE) + { + ios_add_log_message("BTstack Wii: Got inquiry complete; requesting name\n"); + device->state = BTPAD_WII_WANT_NAME; + + bt_send_cmd_ptr(hci_remote_name_request_ptr, device->address, device->page_scan_repetition_mode, + 0, device->clock_offset | 0x8000); + } + } + else if(device->state == BTPAD_WII_WANT_NAME) + { + if (packet[0] == HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE) + { + bd_addr_t event_addr; + bt_flip_addr_ptr(event_addr, &packet[3]); + + if (BD_ADDR_CMP(event_addr, device->address) == 0) + { + if (strncmp((char*)&packet[9], "Nintendo RVL-CNT-01", 19) == 0) + { + ios_add_log_message("BTstack Wii: Got Nintendo RVL-CNT-01; Connecting"); + device->state = BTPAD_WII_CONNECTING; + + bt_send_cmd_ptr(l2cap_create_channel_ptr, device->address, PSM_HID_CONTROL); + } + else + { + ios_add_log_message("BTstack Wii: Unrecognized device %s; Will keep looking", (char*)&packet[9]); + memset(device, 0, sizeof(*device)); + + device->state = BTPAD_WII_WAITING; + bt_send_cmd_ptr(hci_inquiry_ptr, HCI_INQUIRY_LAP, 3, 0); + } + } + else + ios_add_log_message("BTstack Wii: Connection unexpected; ignoring"); + } + } + else if(device->state == BTPAD_WII_CONNECTING) + { + if (packet[0] == L2CAP_EVENT_CHANNEL_OPENED) + { + bd_addr_t event_addr; + bt_flip_addr_ptr(event_addr, &packet[3]); + if (BD_ADDR_CMP(device->address, event_addr) != 0) + { + ios_add_log_message("BTstack Wii: Incoming L2CAP connection not recognized; ignoring"); + return; + } + + const uint16_t psm = READ_BT_16(packet, 11); + + if (packet[2] == 0) + { + ios_add_log_message("BTstack: WiiMote L2CAP channel opened: %02X\n", psm); + + if (psm == PSM_HID_CONTROL) + { + ios_add_log_message("BTstack Wii: Got HID CONTROL channel; Opening INTERRUPT"); + bt_send_cmd_ptr(l2cap_create_channel_ptr, device->address, PSM_HID_INTERRUPT); + + memset(&device->wiimote, 0, sizeof(struct wiimote_t)); + device->wiimote.c_source_cid = READ_BT_16(packet, 13); + device->wiimote.wiiMoteConHandle = READ_BT_16(packet, 9); + memcpy(&device->wiimote.addr, &device->address, BD_ADDR_LEN); + device->wiimote.exp.type = EXP_NONE; + } + else if (psm == PSM_HID_INTERRUPT) + { + ios_add_log_message("BTstack Wii: Got HID INTERRUPT channel; Connected"); + device->state = BTPAD_WII_CONNECTED; + + device->wiimote.i_source_cid = READ_BT_16(packet, 13); + device->wiimote.state = WIIMOTE_STATE_CONNECTED; + wiimote_handshake(&device->wiimote, -1, NULL, -1); + } + } + else + { + ios_add_log_message("BTstack Wii: Failed to open WiiMote L2CAP channel for PSM: %02X", psm); + } + } + } + } + else if(packet_type == L2CAP_DATA_PACKET) + { + byte* msg = packet + 2; + + switch (packet[1]) + { + case WM_RPT_BTN: + { + wiimote_pressed_buttons(&device->wiimote, msg); + break; + } + + case WM_RPT_READ: + { + wiimote_pressed_buttons(&device->wiimote, msg); + + byte len = ((msg[2] & 0xF0) >> 4) + 1; + byte *data = (msg + 5); + + wiimote_handshake(&device->wiimote, WM_RPT_READ, data, len); + return; + } + + case WM_RPT_CTRL_STATUS: + { + wiimote_pressed_buttons(&device->wiimote, msg); + wiimote_handshake(&device->wiimote,WM_RPT_CTRL_STATUS,msg,-1); + + return; + } + + case WM_RPT_BTN_EXP: + { + wiimote_pressed_buttons(&device->wiimote, msg); + wiimote_handle_expansion(&device->wiimote, msg+2); + break; + } + } + } +} + +struct btpad_interface btpad_wii = +{ + (void*)&btpad_wii_connect, + (void*)&btpad_wii_disconnect, + (void*)&btpad_wii_setleds, + (void*)&btpad_wii_get_buttons, + (void*)&btpad_wii_packet_handler +}; diff --git a/ios/RetroArch/settings/RASettingsList.m b/ios/RetroArch/settings/RASettingsList.m index e62ab76449..c5148ce2cc 100644 --- a/ios/RetroArch/settings/RASettingsList.m +++ b/ios/RetroArch/settings/RASettingsList.m @@ -133,9 +133,9 @@ static RASettingData* custom_action(NSString* action) (void)[[RASettingsList alloc] init]; } -- (RASettingsList*)initWithModule:(RAModuleInfo*)module +- (id)init { - config_file_t* config = config_file_new([module.configPath UTF8String]); + config_file_t* config = config_file_new([[RetroArch_iOS get].moduleInfo.configPath UTF8String]); NSString* overlay_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/overlays/"]; NSString* shader_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/shaders/"]; diff --git a/ps3/rgl/src/ps3/include/rgl-externs.h b/ps3/rgl/src/ps3/include/rgl-externs.h index 1465905a26..e8046fe583 100644 --- a/ps3/rgl/src/ps3/include/rgl-externs.h +++ b/ps3/rgl/src/ps3/include/rgl-externs.h @@ -2,7 +2,6 @@ void rglGcmFifoFinish (void *data); GLboolean rglGcmFifoReferenceInUse (void *data, GLuint reference); GLuint rglGcmFifoPutReference (void *data); void rglGcmFifoFlush (void *data); -uint32_t *rglGcmFifoWaitForFreeSpace (void *data, GLuint spaceInWords); void rglGcmGetTileRegionInfo (void *data, GLuint *address, GLuint *size); GLboolean rglGcmTryResizeTileRegion( GLuint address, GLuint size, void *data); diff --git a/ps3/rgl/src/ps3/rgl_ps3.cpp b/ps3/rgl/src/ps3/rgl_ps3.cpp index 7f74f1ecf6..0961fcbc8e 100644 --- a/ps3/rgl/src/ps3/rgl_ps3.cpp +++ b/ps3/rgl/src/ps3/rgl_ps3.cpp @@ -1500,19 +1500,6 @@ GLboolean rglGcmFifoReferenceInUse (void *data, GLuint reference) return GL_TRUE; } -// Wait until the requested space is available. -// If not currently available, will call the out of space callback - -uint32_t * rglGcmFifoWaitForFreeSpace (void *data, GLuint spaceInWords) -{ - rglGcmFifo *fifo = (rglGcmFifo*)data; - - if ( fifo->current + spaceInWords + 1024 > fifo->end ) - rglOutOfSpaceCallback( fifo, spaceInWords ); - - return rglGcmState_i.fifo.current; -} - void rglGcmFifoInit (void *data, void *dmaControl, unsigned long dmaPushBufferOffset, uint32_t*dmaPushBuffer, GLuint dmaPushBufferSize ) { @@ -2065,15 +2052,10 @@ int32_t rglOutOfSpaceCallback (void *data, uint32_t spaceInWords) // If the current end isn't the same as the full fifo end we // aren't at the end. Just go ahead and set the next begin and end if(fifo->end != fifo->dmaPushBufferEnd) - { nextbegin = (uint32_t *)fifo->end + 1; - nextend = nextbegin + fifo->fifoBlockSize/sizeof(uint32_t) - 1; - } else - { nextbegin = (uint32_t *)fifo->dmaPushBufferBegin; - nextend = nextbegin + (fifo->fifoBlockSize)/sizeof(uint32_t) - 1; - } + nextend = nextbegin + (fifo->fifoBlockSize)/sizeof(uint32_t) - 1; cellGcmAddressToOffset(nextbegin, &nextbeginoffset); cellGcmAddressToOffset(nextend, &nextendoffset); @@ -2087,8 +2069,6 @@ int32_t rglOutOfSpaceCallback (void *data, uint32_t spaceInWords) fifo->current = nextbegin; fifo->end = nextend; - const GLuint nopsAtBegin = 8; - //if Gpu busy with the new area, stall and flush uint32_t get = fifo->dmaControl->Get; @@ -2106,17 +2086,15 @@ int32_t rglOutOfSpaceCallback (void *data, uint32_t spaceInWords) while(((get >= nextbeginoffset) && (get <= nextendoffset)) || ((0 <= get) && (get < 0x10000))) { - // Don't be a ppu hog ;) - sys_timer_usleep(30); get = fifo->dmaControl->Get; cellGcmIoOffsetToAddress( get, &getEA ); } // need to add some nops here at the beginning for a issue with the get and the put being at the // same position when the fifo is in GPU memory. - for ( GLuint i = 0; i < nopsAtBegin; i++ ) + for ( GLuint i = 0; i < 8; i++ ) { - fifo->current[0] = RGLGCM_NOP(); + fifo->current[0] = 0; fifo->current++; } diff --git a/ps3/rgl/src/ps3/rgl_ps3_raster.cpp b/ps3/rgl/src/ps3/rgl_ps3_raster.cpp index c1b891d092..74880a4486 100644 --- a/ps3/rgl/src/ps3/rgl_ps3_raster.cpp +++ b/ps3/rgl/src/ps3/rgl_ps3_raster.cpp @@ -1664,88 +1664,86 @@ static inline void rglValidateStates (GLuint mask) long unit = unitsInUse[i]; rglTexture* texture = LContext->TextureImageUnits[unit].currentTexture; - if (texture) + if (!texture) + continue; + + // Validate resources of a texture and set it to a unit + + if (RGL_UNLIKELY( texture->revalidate)) + rglPlatformValidateTextureResources(texture); // this updates the isComplete bit. + + GLboolean isCompleteCache = texture->isComplete; + + if (RGL_LIKELY(isCompleteCache)) { - // Validate resources of a texture and set it to a unit - - if (RGL_UNLIKELY( texture->revalidate)) - rglPlatformValidateTextureResources(texture); // this updates the isComplete bit. + // Set a texture to a gcm texture unit - GLboolean isCompleteCache = texture->isComplete; + rglGcmTexture *platformTexture = ( rglGcmTexture * )texture->platformTexture; + const GLuint imageOffset = gmmIdToOffset(platformTexture->gpuAddressId) + + platformTexture->gpuAddressIdOffset; + platformTexture->gcmTexture.offset = imageOffset; - if (RGL_LIKELY(isCompleteCache)) - { - // Set a texture to a gcm texture unit + // set up the texture unit with the info for the current texture + // bind texture , control 1,3,format and remap - rglGcmTexture *platformTexture = ( rglGcmTexture * )texture->platformTexture; - const GLuint imageOffset = gmmIdToOffset(platformTexture->gpuAddressId) + - platformTexture->gpuAddressIdOffset; - platformTexture->gcmTexture.offset = imageOffset; + GCM_FUNC_SAFE( cellGcmSetTexture, unit, &platformTexture->gcmTexture ); + CellGcmContextData *gcm_context = (CellGcmContextData*)&rglGcmState_i.fifo; + cellGcmReserveMethodSizeInline(gcm_context, 11); + uint32_t *current = gcm_context->current; + current[0] = CELL_GCM_METHOD_HEADER_TEXTURE_OFFSET(unit, 8); + current[1] = CELL_GCM_METHOD_DATA_TEXTURE_OFFSET(platformTexture->gcmTexture.offset); + current[2] = CELL_GCM_METHOD_DATA_TEXTURE_FORMAT(platformTexture->gcmTexture.location, + platformTexture->gcmTexture.cubemap, + platformTexture->gcmTexture.dimension, + platformTexture->gcmTexture.format, + platformTexture->gcmTexture.mipmap); + current[3] = CELL_GCM_METHOD_DATA_TEXTURE_ADDRESS( platformTexture->gcmMethods.address.wrapS, + platformTexture->gcmMethods.address.wrapT, + platformTexture->gcmMethods.address.wrapR, + platformTexture->gcmMethods.address.unsignedRemap, + platformTexture->gcmMethods.address.zfunc, + platformTexture->gcmMethods.address.gamma, + 0); + current[4] = CELL_GCM_METHOD_DATA_TEXTURE_CONTROL0(CELL_GCM_TRUE, + platformTexture->gcmMethods.control0.minLOD, + platformTexture->gcmMethods.control0.maxLOD, + platformTexture->gcmMethods.control0.maxAniso); + current[5] = platformTexture->gcmTexture.remap; + current[6] = CELL_GCM_METHOD_DATA_TEXTURE_FILTER( + (platformTexture->gcmMethods.filter.bias & 0x1fff), + platformTexture->gcmMethods.filter.min, + platformTexture->gcmMethods.filter.mag, + platformTexture->gcmMethods.filter.conv); + current[7] = CELL_GCM_METHOD_DATA_TEXTURE_IMAGE_RECT( + platformTexture->gcmTexture.height, + platformTexture->gcmTexture.width); + current[8] = CELL_GCM_METHOD_DATA_TEXTURE_BORDER_COLOR( + platformTexture->gcmMethods.borderColor); + current[9] = CELL_GCM_METHOD_HEADER_TEXTURE_CONTROL3(unit,1); + current[10] = CELL_GCM_METHOD_DATA_TEXTURE_CONTROL3( + platformTexture->gcmTexture.pitch, + platformTexture->gcmTexture.depth); + gcm_context->current = ¤t[11]; + } + else + { + // Validate incomplete texture by remapping + //RGL_REPORT_EXTRA( RGL_REPORT_TEXTURE_INCOMPLETE, "Texture %d bound to unit %d(%s) is incomplete.", texture->name, unit, rglGetGLEnumName( texture->target ) ); + GLuint remap = CELL_GCM_REMAP_MODE( + CELL_GCM_TEXTURE_REMAP_ORDER_XYXY, + CELL_GCM_TEXTURE_REMAP_FROM_A, + CELL_GCM_TEXTURE_REMAP_FROM_R, + CELL_GCM_TEXTURE_REMAP_FROM_G, + CELL_GCM_TEXTURE_REMAP_FROM_B, + CELL_GCM_TEXTURE_REMAP_ONE, + CELL_GCM_TEXTURE_REMAP_ZERO, + CELL_GCM_TEXTURE_REMAP_ZERO, + CELL_GCM_TEXTURE_REMAP_ZERO ); - // set up the texture unit with the info for the current texture - // bind texture , control 1,3,format and remap - // [YLIN] Contiguous GCM calls in fact will cause LHSs between them - // There is no walkaround for this but not to use GCM functions - - GCM_FUNC_SAFE( cellGcmSetTexture, unit, &platformTexture->gcmTexture ); - CellGcmContextData *gcm_context = (CellGcmContextData*)&rglGcmState_i.fifo; - cellGcmReserveMethodSizeInline(gcm_context, 11); - uint32_t *current = gcm_context->current; - current[0] = CELL_GCM_METHOD_HEADER_TEXTURE_OFFSET(unit, 8); - current[1] = CELL_GCM_METHOD_DATA_TEXTURE_OFFSET(platformTexture->gcmTexture.offset); - current[2] = CELL_GCM_METHOD_DATA_TEXTURE_FORMAT(platformTexture->gcmTexture.location, - platformTexture->gcmTexture.cubemap, - platformTexture->gcmTexture.dimension, - platformTexture->gcmTexture.format, - platformTexture->gcmTexture.mipmap); - current[3] = CELL_GCM_METHOD_DATA_TEXTURE_ADDRESS( platformTexture->gcmMethods.address.wrapS, - platformTexture->gcmMethods.address.wrapT, - platformTexture->gcmMethods.address.wrapR, - platformTexture->gcmMethods.address.unsignedRemap, - platformTexture->gcmMethods.address.zfunc, - platformTexture->gcmMethods.address.gamma, - 0); - current[4] = CELL_GCM_METHOD_DATA_TEXTURE_CONTROL0(CELL_GCM_TRUE, - platformTexture->gcmMethods.control0.minLOD, - platformTexture->gcmMethods.control0.maxLOD, - platformTexture->gcmMethods.control0.maxAniso); - current[5] = platformTexture->gcmTexture.remap; - current[6] = CELL_GCM_METHOD_DATA_TEXTURE_FILTER( - (platformTexture->gcmMethods.filter.bias & 0x1fff), - platformTexture->gcmMethods.filter.min, - platformTexture->gcmMethods.filter.mag, - platformTexture->gcmMethods.filter.conv); - current[7] = CELL_GCM_METHOD_DATA_TEXTURE_IMAGE_RECT( - platformTexture->gcmTexture.height, - platformTexture->gcmTexture.width); - current[8] = CELL_GCM_METHOD_DATA_TEXTURE_BORDER_COLOR( - platformTexture->gcmMethods.borderColor); - current[9] = CELL_GCM_METHOD_HEADER_TEXTURE_CONTROL3(unit,1); - current[10] = CELL_GCM_METHOD_DATA_TEXTURE_CONTROL3( - platformTexture->gcmTexture.pitch, - platformTexture->gcmTexture.depth); - gcm_context->current = ¤t[11]; - } - else - { - // Validate incomplete texture by remapping - //RGL_REPORT_EXTRA( RGL_REPORT_TEXTURE_INCOMPLETE, "Texture %d bound to unit %d(%s) is incomplete.", texture->name, unit, rglGetGLEnumName( texture->target ) ); - GLuint remap = CELL_GCM_REMAP_MODE( - CELL_GCM_TEXTURE_REMAP_ORDER_XYXY, - CELL_GCM_TEXTURE_REMAP_FROM_A, - CELL_GCM_TEXTURE_REMAP_FROM_R, - CELL_GCM_TEXTURE_REMAP_FROM_G, - CELL_GCM_TEXTURE_REMAP_FROM_B, - CELL_GCM_TEXTURE_REMAP_ONE, - CELL_GCM_TEXTURE_REMAP_ZERO, - CELL_GCM_TEXTURE_REMAP_ZERO, - CELL_GCM_TEXTURE_REMAP_ZERO ); - - // disable control 0 - GCM_FUNC( cellGcmSetTextureControl, unit, CELL_GCM_FALSE, 0, 0, 0 ); - // set texture remap only - GCM_FUNC( cellGcmSetTextureRemap, unit, remap ); - } + // disable control 0 + GCM_FUNC( cellGcmSetTextureControl, unit, CELL_GCM_FALSE, 0, 0, 0 ); + // set texture remap only + GCM_FUNC( cellGcmSetTextureRemap, unit, remap ); } } } @@ -1766,7 +1764,14 @@ static inline void rglValidateStates (GLuint mask) conf.registerCount = program->header.vertexProgram.registerCount; conf.attributeInputMask = program->header.attributeInputMask; - rglGcmFifoWaitForFreeSpace( &rglGcmState_i.fifo, 7 + 5 * conf.instructionCount ); + rglGcmFifo *fifo = (rglGcmFifo*)&rglGcmState_i.fifo; + GLuint spaceInWords = 7 + 5 * conf.instructionCount; + + // Push a CG program onto the current command buffer + + // make sure there is space for the pushbuffer + any nops we need to add for alignment + if ( fifo->current + spaceInWords + 1024 > fifo->end ) + rglOutOfSpaceCallback( fifo, spaceInWords ); GCM_FUNC( cellGcmSetVertexProgramLoad, &conf, program->ucode ); GCM_FUNC( cellGcmSetUserClipPlaneControl, 0, 0, 0, 0, 0, 0 ); @@ -1781,110 +1786,92 @@ static inline void rglValidateStates (GLuint mask) for ( int i = 0;i < count;i++ ) { const CgParameterEntry *parameterEntry = program->parametersEntries + program->defaultValuesIndices[i].entryIndex; - if (( parameterEntry->flags & CGPF_REFERENCED ) && ( parameterEntry->flags & CGPV_MASK ) == CGPV_CONSTANT ) + GLboolean cond = (( parameterEntry->flags & CGPF_REFERENCED ) + && ( parameterEntry->flags & CGPV_MASK ) == CGPV_CONSTANT ); + + if (!cond) + continue; + + const float *value = program->defaultValues + + program->defaultValuesIndices[i].defaultValueIndex; + + const CgParameterResource *parameterResource = rglGetParameterResource( program, parameterEntry ); + + GLboolean cond2 = parameterResource->resource != (unsigned short) - 1; + + if (!cond2) + continue; + + switch ( parameterResource->type ) { - const float *value = program->defaultValues + - program->defaultValuesIndices[i].defaultValueIndex; - - const CgParameterResource *parameterResource = rglGetParameterResource( program, parameterEntry ); - - if (parameterResource->resource != (unsigned short) - 1) - { - switch ( parameterResource->type ) + case CG_FLOAT: + case CG_FLOAT1: + case CG_FLOAT2: + case CG_FLOAT3: + case CG_FLOAT4: + case CG_HALF: + case CG_HALF1: + case CG_HALF2: + case CG_HALF3: + case CG_HALF4: + case CG_INT: + case CG_INT1: + case CG_INT2: + case CG_INT3: + case CG_INT4: + case CG_BOOL: + case CG_BOOL1: + case CG_BOOL2: + case CG_BOOL3: + case CG_BOOL4: + case CG_FIXED: + case CG_FIXED1: + case CG_FIXED2: + case CG_FIXED3: + case CG_FIXED4: + GCM_FUNC( cellGcmSetVertexProgramParameterBlock, parameterResource->resource, 1, value ); // GCM_PORT_TESTED [Cedric] + break; + case CG_FLOAT4x4: + case CG_HALF4x4: + case CG_INT4x4: + case CG_BOOL4x4: + case CG_FIXED4x4: + // set 4 consts { - case CG_FLOAT: - case CG_FLOAT1: - case CG_FLOAT2: - case CG_FLOAT3: - case CG_FLOAT4: - GCM_FUNC( cellGcmSetVertexProgramParameterBlock, parameterResource->resource, 1, value ); // GCM_PORT_TESTED [Cedric] - break; - case CG_FLOAT4x4: - // set 4 consts - { - GLfloat v2[16]; - v2[0] = value[0];v2[1] = value[4];v2[2] = value[8];v2[3] = value[12]; - v2[4] = value[1];v2[5] = value[5];v2[6] = value[9];v2[7] = value[13]; - v2[8] = value[2];v2[9] = value[6];v2[10] = value[10];v2[11] = value[14]; - v2[12] = value[3];v2[13] = value[7];v2[14] = value[11];v2[15] = value[15]; - GCM_FUNC( cellGcmSetVertexProgramParameterBlock, parameterResource->resource, 4, v2 ); // GCM_PORT_TESTED [Cedric] - } - break; - case CG_FLOAT3x3: - // set 3 consts - { - GLfloat v2[12]; - v2[0] = value[0];v2[1] = value[3];v2[2] = value[6];v2[3] = 0; - v2[4] = value[1];v2[5] = value[4];v2[6] = value[7];v2[7] = 0; - v2[8] = value[2];v2[9] = value[5];v2[10] = value[8];v2[11] = 0; - GCM_FUNC( cellGcmSetVertexProgramParameterBlock, parameterResource->resource, 3, v2 ); - } - break; - case CG_HALF: - case CG_HALF1: - case CG_HALF2: - case CG_HALF3: - case CG_HALF4: - case CG_INT: - case CG_INT1: - case CG_INT2: - case CG_INT3: - case CG_INT4: - case CG_BOOL: - case CG_BOOL1: - case CG_BOOL2: - case CG_BOOL3: - case CG_BOOL4: - case CG_FIXED: - case CG_FIXED1: - case CG_FIXED2: - case CG_FIXED3: - case CG_FIXED4: - GCM_FUNC( cellGcmSetVertexProgramParameterBlock, parameterResource->resource, 1, value ); // GCM_PORT_TESTED [Cedric] - break; - case CG_HALF4x4: - case CG_INT4x4: - case CG_BOOL4x4: - case CG_FIXED4x4: - // set 4 consts - { - GLfloat v2[16]; - v2[0] = value[0]; - v2[1] = value[4]; - v2[2] = value[8]; - v2[3] = value[12]; - v2[4] = value[1]; - v2[5] = value[5]; - v2[6] = value[9]; - v2[7] = value[13]; - v2[8] = value[2]; - v2[9] = value[6]; - v2[10] = value[10]; - v2[11] = value[14]; - v2[12] = value[3]; - v2[13] = value[7]; - v2[14] = value[11]; - v2[15] = value[15]; - GCM_FUNC( cellGcmSetVertexProgramParameterBlock, parameterResource->resource, 4, v2 ); // GCM_PORT_TESTED [Cedric] - } - break; - case CG_HALF3x3: - case CG_INT3x3: - case CG_BOOL3x3: - case CG_FIXED3x3: - // set 3 consts - { - GLfloat v2[12]; - v2[0] = value[0];v2[1] = value[3];v2[2] = value[6];v2[3] = 0; - v2[4] = value[1];v2[5] = value[4];v2[6] = value[7];v2[7] = 0; - v2[8] = value[2];v2[9] = value[5];v2[10] = value[8];v2[11] = 0; - GCM_FUNC( cellGcmSetVertexProgramParameterBlock, parameterResource->resource, 3, v2 ); - } - break; - default: - break; + GLfloat v2[16]; + v2[0] = value[0]; + v2[1] = value[4]; + v2[2] = value[8]; + v2[3] = value[12]; + v2[4] = value[1]; + v2[5] = value[5]; + v2[6] = value[9]; + v2[7] = value[13]; + v2[8] = value[2]; + v2[9] = value[6]; + v2[10] = value[10]; + v2[11] = value[14]; + v2[12] = value[3]; + v2[13] = value[7]; + v2[14] = value[11]; + v2[15] = value[15]; + GCM_FUNC( cellGcmSetVertexProgramParameterBlock, parameterResource->resource, 4, v2 ); // GCM_PORT_TESTED [Cedric] } - } + break; + case CG_FLOAT3x3: + case CG_HALF3x3: + case CG_INT3x3: + case CG_BOOL3x3: + case CG_FIXED3x3: + // set 3 consts + { + GLfloat v2[12]; + v2[0] = value[0];v2[1] = value[3];v2[2] = value[6];v2[3] = 0; + v2[4] = value[1];v2[5] = value[4];v2[6] = value[7];v2[7] = 0; + v2[8] = value[2];v2[9] = value[5];v2[10] = value[8];v2[11] = 0; + GCM_FUNC( cellGcmSetVertexProgramParameterBlock, parameterResource->resource, 3, v2 ); + } + break; } } @@ -1896,11 +1883,14 @@ static inline void rglValidateStates (GLuint mask) if (RGL_LIKELY(needValidate & RGL_VALIDATE_VERTEX_CONSTANTS) || validate_vertex_consts) { _CGprogram *cgprog = LContext->BoundVertexProgram; + rglGcmFifo *fifo = (rglGcmFifo*)&rglGcmState_i.fifo; + GLuint spaceInWords = cgprog->constantPushBufferWordSize + 4 + 32; // Push a CG program onto the current command buffer // make sure there is space for the pushbuffer + any nops we need to add for alignment - rglGcmFifoWaitForFreeSpace( &rglGcmState_i.fifo, cgprog->constantPushBufferWordSize + 4 + 32); + if ( fifo->current + spaceInWords + 1024 > fifo->end ) + rglOutOfSpaceCallback( fifo, spaceInWords ); // first add nops to get us the next alligned position in the fifo // [YLIN] Use VMX register to copy