mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 19:45:20 +00:00
video: Allow selection of 3D stereo resolutions
This commit is contained in:
parent
19107b2de5
commit
6e3406b3f5
6 changed files with 116 additions and 53 deletions
|
@ -300,6 +300,14 @@ error_code cellVideoOutGetScreenSize(u32 videoOut, vm::ptr<f32> screenSize)
|
|||
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
|
||||
}
|
||||
|
||||
if (g_cfg.video.enable_3d)
|
||||
{
|
||||
// Return Playstation 3D display value
|
||||
// Some games call this function when 3D is enabled
|
||||
*screenSize = 24.f;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
// TODO: Use virtual screen size
|
||||
#ifdef _WIN32
|
||||
// HDC screen = GetDC(NULL);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
LOG_CHANNEL(cellSysutil);
|
||||
|
||||
// NOTE: Unused in this module, but used by gs_frame to determine window size
|
||||
const extern std::unordered_map<video_resolution, std::pair<int, int>, value_hash<video_resolution>> g_video_out_resolution_map
|
||||
{
|
||||
{ video_resolution::_1080, { 1920, 1080 } },
|
||||
|
@ -62,6 +63,41 @@ void fmt_class_string<CellVideoOutError>::format(std::string& out, u64 arg)
|
|||
|
||||
error_code cellVideoOutGetNumberOfDevice(u32 videoOut);
|
||||
|
||||
error_code _IntGetResolutionInfo(u8 resolution_id, CellVideoOutResolution* resolution)
|
||||
{
|
||||
// NOTE: Some resolution IDs that return values on hw have unknown resolution enumerants
|
||||
switch (resolution_id)
|
||||
{
|
||||
case CELL_VIDEO_OUT_RESOLUTION_1080: *resolution = { 0x780, 0x438 }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_720: *resolution = { 0x500, 0x2d0 }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_480: *resolution = { 0x2d0, 0x1e0 }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_576: *resolution = { 0x2d0, 0x240 }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_1600x1080: *resolution = { 0x640, 0x438 }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_1440x1080: *resolution = { 0x5a0, 0x438 }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_1280x1080: *resolution = { 0x500, 0x438 }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_960x1080: *resolution = { 0x3c0, 0x438 }; break;
|
||||
case 0x64: *resolution = { 0x550, 0x300 }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING: *resolution = { 0x500, 0x5be }; break;
|
||||
case 0x82: *resolution = { 0x780, 0x438 }; break;
|
||||
case 0x83: *resolution = { 0x780, 0x89d }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_640x720_3D_FRAME_PACKING: *resolution = { 0x280, 0x5be }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_800x720_3D_FRAME_PACKING: *resolution = { 0x320, 0x5be }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_960x720_3D_FRAME_PACKING: *resolution = { 0x3c0, 0x5be }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_1024x720_3D_FRAME_PACKING: *resolution = { 0x400, 0x5be }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_720_DUALVIEW_FRAME_PACKING: *resolution = { 0x500, 0x5be }; break;
|
||||
case 0x92: *resolution = { 0x780, 0x438 }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_640x720_DUALVIEW_FRAME_PACKING: *resolution = { 0x280, 0x5be }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_800x720_DUALVIEW_FRAME_PACKING: *resolution = { 0x320, 0x5be }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_960x720_DUALVIEW_FRAME_PACKING: *resolution = { 0x3c0, 0x5be }; break;
|
||||
case CELL_VIDEO_OUT_RESOLUTION_1024x720_DUALVIEW_FRAME_PACKING: *resolution = { 0x400, 0x5be }; break;
|
||||
case 0xa1: *resolution = { 0x780, 0x438 }; break;
|
||||
|
||||
default: return CELL_VIDEO_OUT_ERROR_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellVideoOutGetState(u32 videoOut, u32 deviceIndex, vm::ptr<CellVideoOutState> state)
|
||||
{
|
||||
cellSysutil.trace("cellVideoOutGetState(videoOut=%d, deviceIndex=%d, state=*0x%x)", videoOut, deviceIndex, state);
|
||||
|
@ -90,6 +126,7 @@ error_code cellVideoOutGetState(u32 videoOut, u32 deviceIndex, vm::ptr<CellVideo
|
|||
state->displayMode.conversion = CELL_VIDEO_OUT_DISPLAY_CONVERSION_NONE;
|
||||
state->displayMode.aspect = conf->state? conf->aspect : g_video_out_aspect_id.at(g_cfg.video.aspect_ratio);
|
||||
state->displayMode.refreshRates = CELL_VIDEO_OUT_REFRESH_RATE_59_94HZ;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -110,36 +147,15 @@ error_code cellVideoOutGetResolution(u32 resolutionId, vm::ptr<CellVideoOutResol
|
|||
return CELL_VIDEO_OUT_ERROR_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
switch (resolutionId)
|
||||
{
|
||||
case 0x01: *resolution = { 0x780, 0x438 }; break;
|
||||
case 0x02: *resolution = { 0x500, 0x2d0 }; break;
|
||||
case 0x04: *resolution = { 0x2d0, 0x1e0 }; break;
|
||||
case 0x05: *resolution = { 0x2d0, 0x240 }; break;
|
||||
case 0x0a: *resolution = { 0x640, 0x438 }; break;
|
||||
case 0x0b: *resolution = { 0x5a0, 0x438 }; break;
|
||||
case 0x0c: *resolution = { 0x500, 0x438 }; break;
|
||||
case 0x0d: *resolution = { 0x3c0, 0x438 }; break;
|
||||
case 0x64: *resolution = { 0x550, 0x300 }; break;
|
||||
case 0x81: *resolution = { 0x500, 0x5be }; break;
|
||||
case 0x82: *resolution = { 0x780, 0x438 }; break;
|
||||
case 0x83: *resolution = { 0x780, 0x89d }; break;
|
||||
case 0x8b: *resolution = { 0x280, 0x5be }; break;
|
||||
case 0x8a: *resolution = { 0x320, 0x5be }; break;
|
||||
case 0x89: *resolution = { 0x3c0, 0x5be }; break;
|
||||
case 0x88: *resolution = { 0x400, 0x5be }; break;
|
||||
case 0x91: *resolution = { 0x500, 0x5be }; break;
|
||||
case 0x92: *resolution = { 0x780, 0x438 }; break;
|
||||
case 0x9b: *resolution = { 0x280, 0x5be }; break;
|
||||
case 0x9a: *resolution = { 0x320, 0x5be }; break;
|
||||
case 0x99: *resolution = { 0x3c0, 0x5be }; break;
|
||||
case 0x98: *resolution = { 0x400, 0x5be }; break;
|
||||
case 0xa1: *resolution = { 0x780, 0x438 }; break;
|
||||
CellVideoOutResolution res;
|
||||
error_code result;
|
||||
|
||||
default: return CELL_VIDEO_OUT_ERROR_ILLEGAL_PARAMETER;
|
||||
if (result = _IntGetResolutionInfo(resolutionId, &res); result == CELL_OK)
|
||||
{
|
||||
*resolution = res;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
error_code cellVideoOutConfigure(u32 videoOut, vm::ptr<CellVideoOutConfiguration> config, vm::ptr<CellVideoOutOption> option, u32 waitForEvent)
|
||||
|
@ -161,34 +177,23 @@ error_code cellVideoOutConfigure(u32 videoOut, vm::ptr<CellVideoOutConfiguration
|
|||
return CELL_VIDEO_OUT_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
video_resolution res;
|
||||
|
||||
for (const auto& ares : g_video_out_resolution_id)
|
||||
{
|
||||
if (ares.second == config->resolutionId)
|
||||
{
|
||||
found = true;
|
||||
res = ares.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
CellVideoOutResolution res;
|
||||
if (_IntGetResolutionInfo(config->resolutionId, &res) != CELL_OK ||
|
||||
(config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING && !g_cfg.video.enable_3d))
|
||||
{
|
||||
// Resolution not supported
|
||||
cellSysutil.error("Unusual resolution requested: 0x%x", config->resolutionId);
|
||||
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_DISPLAY_MODE;
|
||||
}
|
||||
|
||||
auto& res_info = g_video_out_resolution_map.at(res);
|
||||
|
||||
auto conf = g_fxo->get<rsx::avconf>();
|
||||
conf->resolution_id = config->resolutionId;
|
||||
conf->_3d = config->resolutionId >= CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING;
|
||||
conf->aspect = config->aspect;
|
||||
conf->format = config->format;
|
||||
conf->scanline_pitch = config->pitch;
|
||||
conf->resolution_x = u32(res_info.first);
|
||||
conf->resolution_y = u32(res_info.second);
|
||||
conf->resolution_x = res.width;
|
||||
conf->resolution_y = res.height;
|
||||
conf->state = 1;
|
||||
|
||||
if (conf->aspect == CELL_VIDEO_OUT_ASPECT_AUTO)
|
||||
|
@ -197,6 +202,8 @@ error_code cellVideoOutConfigure(u32 videoOut, vm::ptr<CellVideoOutConfiguration
|
|||
conf->aspect = g_video_out_aspect_id.at(g_cfg.video.aspect_ratio);
|
||||
}
|
||||
|
||||
cellSysutil.notice("Selected video resolution 0x%x", config->resolutionId);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -215,7 +222,8 @@ error_code cellVideoOutGetConfiguration(u32 videoOut, vm::ptr<CellVideoOutConfig
|
|||
switch (videoOut)
|
||||
{
|
||||
case CELL_VIDEO_OUT_PRIMARY:
|
||||
if (const auto conf = g_fxo->get<rsx::avconf>(); conf->state)
|
||||
{
|
||||
if (auto conf = g_fxo->get<rsx::avconf>(); conf->state)
|
||||
{
|
||||
config->resolutionId = conf->resolution_id;
|
||||
config->format = conf->format;
|
||||
|
@ -227,10 +235,15 @@ error_code cellVideoOutGetConfiguration(u32 videoOut, vm::ptr<CellVideoOutConfig
|
|||
config->resolutionId = g_video_out_resolution_id.at(g_cfg.video.resolution);
|
||||
config->format = CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8;
|
||||
config->aspect = g_video_out_aspect_id.at(g_cfg.video.aspect_ratio);
|
||||
config->pitch = 4 * g_video_out_resolution_map.at(g_cfg.video.resolution).first;
|
||||
|
||||
CellVideoOutResolution res;
|
||||
verify("Invalid video configuration" HERE), _IntGetResolutionInfo(config->resolutionId, &res) == CELL_OK;
|
||||
|
||||
config->pitch = 4 * res.width;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
case CELL_VIDEO_OUT_SECONDARY:
|
||||
|
||||
|
@ -277,6 +290,16 @@ error_code cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, vm::ptr<Cell
|
|||
info->availableModes[0].refreshRates = CELL_VIDEO_OUT_REFRESH_RATE_60HZ | CELL_VIDEO_OUT_REFRESH_RATE_59_94HZ;
|
||||
info->availableModes[0].resolutionId = g_video_out_resolution_id.at(g_cfg.video.resolution);
|
||||
info->availableModes[0].scanMode = CELL_VIDEO_OUT_SCAN_MODE_PROGRESSIVE;
|
||||
|
||||
if (g_cfg.video.enable_3d && g_cfg.video.resolution == video_resolution::_720)
|
||||
{
|
||||
// Register 3D-capable display mode
|
||||
info->availableModes[1] = info->availableModes[0];
|
||||
info->availableModes[1].conversion = CELL_VIDEO_OUT_DISPLAY_CONVERSION_TO_720_3D_FRAME_PACKING;
|
||||
info->availableModes[1].resolutionId = CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING;
|
||||
info->availableModeCount++;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -299,10 +322,38 @@ error_code cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId,
|
|||
|
||||
switch (videoOut)
|
||||
{
|
||||
case CELL_VIDEO_OUT_PRIMARY: return not_an_error(
|
||||
resolutionId == g_video_out_resolution_id.at(g_cfg.video.resolution) + 0u
|
||||
&& (aspect == CELL_VIDEO_OUT_ASPECT_AUTO || aspect == g_video_out_aspect_id.at(g_cfg.video.aspect_ratio) + 0u)
|
||||
);
|
||||
case CELL_VIDEO_OUT_PRIMARY:
|
||||
{
|
||||
// NOTE: Result is boolean
|
||||
if (aspect != CELL_VIDEO_OUT_ASPECT_AUTO && aspect != static_cast<u32>(g_video_out_aspect_id.at(g_cfg.video.aspect_ratio)))
|
||||
{
|
||||
return not_an_error(0);
|
||||
}
|
||||
|
||||
if (resolutionId == static_cast<u32>(g_video_out_resolution_id.at(g_cfg.video.resolution)))
|
||||
{
|
||||
// Perfect match
|
||||
return not_an_error(1);
|
||||
}
|
||||
|
||||
if (g_cfg.video.enable_3d && g_cfg.video.resolution == video_resolution::_720)
|
||||
{
|
||||
switch (resolutionId)
|
||||
{
|
||||
case CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING:
|
||||
case CELL_VIDEO_OUT_RESOLUTION_1024x720_3D_FRAME_PACKING:
|
||||
case CELL_VIDEO_OUT_RESOLUTION_960x720_3D_FRAME_PACKING:
|
||||
case CELL_VIDEO_OUT_RESOLUTION_800x720_3D_FRAME_PACKING:
|
||||
case CELL_VIDEO_OUT_RESOLUTION_640x720_3D_FRAME_PACKING:
|
||||
return not_an_error(1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return not_an_error(0);
|
||||
}
|
||||
|
||||
case CELL_VIDEO_OUT_SECONDARY: return not_an_error(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -104,8 +104,9 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info)
|
|||
if (!buffer_pitch)
|
||||
buffer_pitch = buffer_width * avconfig->get_bpp();
|
||||
|
||||
const u32 video_frame_height = (!avconfig->_3d? avconfig->resolution_y : (avconfig->resolution_y - 30) / 2);
|
||||
buffer_width = std::min(buffer_width, avconfig->resolution_x);
|
||||
buffer_height = std::min(buffer_height, avconfig->resolution_y);
|
||||
buffer_height = std::min(buffer_height, video_frame_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -419,8 +419,9 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
|
|||
if (!buffer_pitch)
|
||||
buffer_pitch = buffer_width * avconfig->get_bpp();
|
||||
|
||||
const u32 video_frame_height = (!avconfig->_3d? avconfig->resolution_y : (avconfig->resolution_y - 30) / 2);
|
||||
buffer_width = std::min(buffer_width, avconfig->resolution_x);
|
||||
buffer_height = std::min(buffer_height, avconfig->resolution_y);
|
||||
buffer_height = std::min(buffer_height, video_frame_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -142,6 +142,7 @@ namespace rsx
|
|||
|
||||
struct avconf
|
||||
{
|
||||
bool _3d = false; // Stereo 3D off
|
||||
u8 format = 0; // XRGB
|
||||
u8 aspect = 0; // AUTO
|
||||
u8 resolution_id = 2; // 720p
|
||||
|
|
|
@ -125,6 +125,7 @@ struct cfg_root : cfg::node
|
|||
cfg::_bool disable_native_float16{ this, "Disable native float16 support", false };
|
||||
cfg::_bool multithreaded_rsx{ this, "Multithreaded RSX", false };
|
||||
cfg::_bool relaxed_zcull_sync{ this, "Relaxed ZCULL Sync", false };
|
||||
cfg::_bool enable_3d{ this, "Enable 3D", false };
|
||||
cfg::_int<1, 8> consequtive_frames_to_draw{ this, "Consecutive Frames To Draw", 1 };
|
||||
cfg::_int<1, 8> consequtive_frames_to_skip{ this, "Consecutive Frames To Skip", 1 };
|
||||
cfg::_int<50, 800> resolution_scale_percent{ this, "Resolution Scale", 100 };
|
||||
|
|
Loading…
Add table
Reference in a new issue