Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bd8edee77f | |||
| 787619cdba | |||
| 7d70be42af | |||
| 9671a654b7 | |||
| 6963157e63 | |||
| 9452c6b08c | |||
| 035875825e | |||
| 837e06e85b | |||
| 9e3132c3fc | |||
| 843d0ed298 | |||
| f7f4c049fc | |||
| 1072540e3e | |||
| 0c8c13b8b7 | |||
| 303a109286 | |||
| f0dc38cadd | |||
| 4efa2266e6 | |||
| 1f7a1e4078 | |||
| 2ead9b1f21 | |||
| ddf5b52360 | |||
| f66468ffcd | |||
| d3405da5c4 | |||
| 020d282868 | |||
| 137821c866 | |||
| e6d2e05b6e | |||
| 7b889a10cc | |||
| 1e1c2007a3 | |||
| 660f491310 | |||
| 670660c244 | |||
| 3d960064ef | |||
| f6d2409b20 | |||
| 39bc897b93 | |||
| 5f35f2ac7d | |||
| e1eb075604 | |||
| d19d9ccd0b | |||
| b4b4ae7a78 | |||
| 149fa9d750 | |||
| 791070c158 | |||
| 3bd2114815 | |||
| 46de48593c | |||
| acd384ae2d | |||
| b77666cbba | |||
| 128ee67bba | |||
| 7417033d7f | |||
| e8a940172c | |||
| 290bdc4566 | |||
| 220aab1fd0 | |||
| 8e9f456029 | |||
| aa450b56f1 | |||
| 6d70f3c237 | |||
| 6384541345 | |||
| ffb014ca3d | |||
| 3c3f92f29b | |||
| 24255f7883 | |||
| 40fa836b81 | |||
| b71caa94ac | |||
| 39658c0c52 | |||
| 9b8522e734 | |||
| 9875bf9c7b | |||
| 4ce4cf5242 | |||
| 52110e0647 | |||
| 19ce0cdc09 | |||
| 2e58f312d5 | |||
| 7523d01e0f | |||
| 7972cb5bdc | |||
| 685d5d3ea3 |
+4
-1
@@ -12,7 +12,7 @@
|
||||
[submodule "llvm"]
|
||||
path = llvm
|
||||
url = https://github.com/llvm-mirror/llvm
|
||||
branch = release_37
|
||||
branch = release_36
|
||||
[submodule "minidx9"]
|
||||
path = minidx9
|
||||
url = https://github.com/hrydgard/minidx9.git
|
||||
@@ -22,3 +22,6 @@
|
||||
[submodule "GSL"]
|
||||
path = GSL
|
||||
url = https://github.com/Microsoft/GSL.git
|
||||
[submodule "libpng"]
|
||||
path = libpng
|
||||
url = https://github.com/RPCS3/libpng
|
||||
|
||||
+6
-3
@@ -33,8 +33,10 @@ git:
|
||||
before_install:
|
||||
# shutdown services on Travis, which may have a memory impact
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
echo "yes" | sudo apt-add-repository 'deb http://repos.codelite.org/wx3.0/ubuntu/ precise universe';
|
||||
sudo apt-get install libwxgtk3.0-dev;
|
||||
sudo apt-add-repository -y ppa:libreoffice/ppa;
|
||||
sudo apt-get update;
|
||||
sudo apt-get install libglew-dev;
|
||||
fi;
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$CXX" = "g++" ]; then
|
||||
export CXX="g++-5" CC="gcc-5" CXXFLAGS="-Wno-format-security";
|
||||
@@ -51,7 +53,7 @@ before_install:
|
||||
fi;
|
||||
|
||||
before_script:
|
||||
- git submodule update --init asmjit ffmpeg rsx_program_decompiler GSL
|
||||
- git submodule update --init asmjit ffmpeg rsx_program_decompiler GSL libpng
|
||||
- mkdir build
|
||||
- cd build
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cmake ..; else cmake .. -DLLVM_DIR=/usr/local/opt/llvm36/lib/llvm-3.6/share/llvm/cmake; fi
|
||||
@@ -73,7 +75,7 @@ addons:
|
||||
- cmake
|
||||
- libopenal-dev
|
||||
- freeglut3-dev
|
||||
- libglew-dev
|
||||
# - libglew-dev apt version is too old
|
||||
- libc6-dev
|
||||
- llvm-3.6
|
||||
- llvm-3.6-dev
|
||||
@@ -83,6 +85,7 @@ addons:
|
||||
- clang-3.6
|
||||
- libstdc++-4.8-dev
|
||||
- lib32stdc++6
|
||||
- zlib1g-dev
|
||||
coverity_scan:
|
||||
project:
|
||||
name: $TRAVIS_REPO_SLUG
|
||||
|
||||
@@ -11,7 +11,12 @@ if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
message( FATAL_ERROR "RPCS3 can only be compiled on 64-bit platforms." )
|
||||
endif()
|
||||
|
||||
# We use libpng's static library and don't need to build the shared library and run the tests
|
||||
set(PNG_SHARED OFF CACHE BOOL "Build shared lib." FORCE)
|
||||
set(PNG_TESTS OFF CACHE BOOL "Build tests." FORCE)
|
||||
|
||||
add_subdirectory( asmjit )
|
||||
add_subdirectory( libpng )
|
||||
# TODO: do real installation, including copying directory structure
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${PROJECT_BINARY_DIR}/bin")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${PROJECT_BINARY_DIR}/bin")
|
||||
|
||||
+2
-2
@@ -530,7 +530,7 @@ template<typename T> class se_t<T, true>
|
||||
static_assert(!std::is_pointer<type>::value, "se_t<> error: invalid type (pointer)");
|
||||
static_assert(!std::is_reference<type>::value, "se_t<> error: invalid type (reference)");
|
||||
static_assert(!std::is_array<type>::value, "se_t<> error: invalid type (array)");
|
||||
static_assert(!std::is_enum<type>::value, "se_t<> error: invalid type (enumeration), use integral type instead");
|
||||
//static_assert(!std::is_enum<type>::value, "se_t<> error: invalid type (enumeration), use integral type instead");
|
||||
static_assert(alignof(type) == alignof(stype), "se_t<> error: unexpected alignment");
|
||||
|
||||
template<typename T2, typename = void> struct bool_converter
|
||||
@@ -642,7 +642,7 @@ template<typename T> class se_t<T, false>
|
||||
static_assert(!std::is_pointer<type>::value, "se_t<> error: invalid type (pointer)");
|
||||
static_assert(!std::is_reference<type>::value, "se_t<> error: invalid type (reference)");
|
||||
static_assert(!std::is_array<type>::value, "se_t<> error: invalid type (array)");
|
||||
static_assert(!std::is_enum<type>::value, "se_t<> error: invalid type (enumeration), use integral type instead");
|
||||
//static_assert(!std::is_enum<type>::value, "se_t<> error: invalid type (enumeration), use integral type instead");
|
||||
|
||||
public:
|
||||
se_t() = default;
|
||||
|
||||
@@ -249,6 +249,7 @@ bool fs::is_dir(const std::string& path)
|
||||
{
|
||||
case ERROR_FILE_NOT_FOUND: errno = ENOENT; break;
|
||||
case ERROR_PATH_NOT_FOUND: errno = ENOENT; break;
|
||||
default: throw EXCEPTION("Unknown Win32 error: 0x%x (%s).", error, path);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -686,8 +687,10 @@ u64 fs::file::read(void* buffer, u64 count) const
|
||||
switch (DWORD error = GetLastError())
|
||||
{
|
||||
case ERROR_INVALID_HANDLE: errno = EBADF; break;
|
||||
default: throw EXCEPTION("Unknown Win32 error: 0x%x.", error);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nread;
|
||||
|
||||
@@ -199,6 +199,16 @@ namespace fs
|
||||
CHECK_ASSERTION(seek(0) != -1 && read(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
// Read full file to std::vector
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, std::vector<T>> to_vector() const
|
||||
{
|
||||
std::vector<T> result;
|
||||
result.resize(size() / sizeof(T));
|
||||
CHECK_ASSERTION(seek(0) != -1 && read(result));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO
|
||||
|
||||
+10
-11
@@ -794,16 +794,18 @@ size_t get_x64_access_size(x64_context* context, x64_op_t op, x64_reg_t reg, siz
|
||||
return d_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback that can be customised by GSRender backends to track memory access.
|
||||
* Backends can protect memory pages and get this callback called when an access
|
||||
* violation is met.
|
||||
* Should return true if the backend handles the access violation.
|
||||
*/
|
||||
std::function<bool(u32 addr)> gfxHandler = [](u32) { return false; };
|
||||
namespace rsx
|
||||
{
|
||||
extern std::function<bool(u32 addr, bool is_writing)> g_access_violation_handler;
|
||||
}
|
||||
|
||||
bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
{
|
||||
if (rsx::g_access_violation_handler && rsx::g_access_violation_handler(addr, is_writing))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
auto code = (const u8*)RIP(context);
|
||||
|
||||
x64_op_t op;
|
||||
@@ -811,9 +813,6 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
size_t d_size;
|
||||
size_t i_size;
|
||||
|
||||
if (gfxHandler(addr))
|
||||
return true;
|
||||
|
||||
// decode single x64 instruction that causes memory access
|
||||
decode_x64_reg_op(code, op, reg, d_size, i_size);
|
||||
|
||||
@@ -1131,7 +1130,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
// Throw virtual memory access violation exception
|
||||
[[noreturn]] void throw_access_violation(const char* cause, u32 address) // Don't change function definition
|
||||
{
|
||||
//throw EXCEPTION("Access violation %s location 0x%08x", cause, address);
|
||||
throw EXCEPTION("Access violation %s location 0x%08x", cause, address);
|
||||
}
|
||||
|
||||
// Modify context in order to convert hardware exception to C++ exception
|
||||
|
||||
+5
-3
@@ -14,10 +14,11 @@ branches:
|
||||
|
||||
before_build:
|
||||
# until git for win 2.5 release with commit checkout
|
||||
- git submodule update --init ffmpeg asmjit minidx9 rsx_program_decompiler GSL
|
||||
- git submodule update --init ffmpeg asmjit minidx9 rsx_program_decompiler GSL libpng
|
||||
- 7z x wxWidgets.7z -aos -oC:\rpcs3\wxWidgets > null
|
||||
- if %configuration%==Release (cmake -G "Visual Studio 14 Win64")
|
||||
else (7z x llvmlibs.7z -aos -oC:\rpcs3 > null && cmake -G "Visual Studio 14 Win64" -DLLVM_DIR=C:/rpcs3/llvm_build/share/llvm/cmake)
|
||||
- 7z x zlib.7z -aos -oC:\rpcs3\ > null
|
||||
- if %configuration%==Release (cmake -G "Visual Studio 14 Win64" -DZLIB_ROOT=C:/rpcs3/zlib/)
|
||||
else (7z x llvmlibs.7z -aos -oC:\rpcs3 > null && cmake -G "Visual Studio 14 Win64" -DLLVM_DIR=C:/rpcs3/llvm_build/share/llvm/cmake -DZLIB_ROOT=C:/rpcs3/zlib/)
|
||||
|
||||
build_script:
|
||||
- cmake --build . --config Release -- /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
@@ -25,6 +26,7 @@ build_script:
|
||||
install:
|
||||
- ps: Start-FileDownload 'https://402331b94f8e4b87ae2ef4677347f7956cf3861f.googledrive.com/host/0B6v_qtb9hkicfmt0NG0wTTRtUmF4X3VTQk5Oc2JidEVKVnUteDA1dXdrYlNsVW9kREpsSHc/wxWidgets.7z'
|
||||
- ps: Start-FileDownload 'https://402331b94f8e4b87ae2ef4677347f7956cf3861f.googledrive.com/host/0B6v_qtb9hkicfmt0NG0wTTRtUmF4X3VTQk5Oc2JidEVKVnUteDA1dXdrYlNsVW9kREpsSHc/llvmlibs.7z'
|
||||
- ps: Start-FileDownload 'https://402331b94f8e4b87ae2ef4677347f7956cf3861f.googledrive.com/host/0B6v_qtb9hkicfmt0NG0wTTRtUmF4X3VTQk5Oc2JidEVKVnUteDA1dXdrYlNsVW9kREpsSHc/zlib.7z'
|
||||
- set WXWIN=C:\rpcs3\wxWidgets
|
||||
- set OPENALDIR=C:\rpcs3\OpenAL
|
||||
- set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;C:\wxWidgets;%PATH%
|
||||
|
||||
Submodule
+1
Submodule libpng added at ea77a6fd49
+1
-1
Submodule llvm updated: 33c352b3ed...19ade095e8
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -210,19 +210,15 @@ interface ID2D1GeometryRealization
|
||||
|
||||
#define ID2D1GeometryRealization_QueryInterface(This, riid, ppv) \
|
||||
((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv))
|
||||
#pragma deprecated("ID2D1GeometryRealization_QueryInterface")
|
||||
|
||||
#define ID2D1GeometryRealization_AddRef(This) \
|
||||
((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This))
|
||||
#pragma deprecated("ID2D1GeometryRealization_AddRef")
|
||||
|
||||
#define ID2D1GeometryRealization_Release(This) \
|
||||
((This)->lpVtbl->Base.Base.Release((IUnknown *)This))
|
||||
#pragma deprecated("ID2D1GeometryRealization_Release")
|
||||
|
||||
#define ID2D1GeometryRealization_GetFactory(This, factory) \
|
||||
((This)->lpVtbl->Base.GetFactory((ID2D1Resource *)This, factory))
|
||||
#pragma deprecated("ID2D1GeometryRealization_GetFactory")
|
||||
|
||||
typedef interface ID2D1DeviceContext1 ID2D1DeviceContext1;
|
||||
|
||||
@@ -263,351 +259,264 @@ interface ID2D1DeviceContext1
|
||||
|
||||
#define ID2D1DeviceContext1_QueryInterface(This, riid, ppv) \
|
||||
((This)->lpVtbl->Base.Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv))
|
||||
#pragma deprecated("ID2D1DeviceContext1_QueryInterface")
|
||||
|
||||
#define ID2D1DeviceContext1_AddRef(This) \
|
||||
((This)->lpVtbl->Base.Base.Base.Base.AddRef((IUnknown *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_AddRef")
|
||||
|
||||
#define ID2D1DeviceContext1_Release(This) \
|
||||
((This)->lpVtbl->Base.Base.Base.Base.Release((IUnknown *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_Release")
|
||||
|
||||
#define ID2D1DeviceContext1_GetFactory(This, factory) \
|
||||
((This)->lpVtbl->Base.Base.Base.GetFactory((ID2D1Resource *)This, factory))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetFactory")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateSharedBitmap(This, riid, data, bitmapProperties, bitmap) \
|
||||
((This)->lpVtbl->Base.Base.CreateSharedBitmap((ID2D1RenderTarget *)This, riid, data, bitmapProperties, bitmap))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateSharedBitmap")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateSolidColorBrush(This, color, brushProperties, solidColorBrush) \
|
||||
((This)->lpVtbl->Base.Base.CreateSolidColorBrush((ID2D1RenderTarget *)This, color, brushProperties, solidColorBrush))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateSolidColorBrush")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateLinearGradientBrush(This, linearGradientBrushProperties, brushProperties, gradientStopCollection, linearGradientBrush) \
|
||||
((This)->lpVtbl->Base.Base.CreateLinearGradientBrush((ID2D1RenderTarget *)This, linearGradientBrushProperties, brushProperties, gradientStopCollection, linearGradientBrush))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateLinearGradientBrush")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateRadialGradientBrush(This, radialGradientBrushProperties, brushProperties, gradientStopCollection, radialGradientBrush) \
|
||||
((This)->lpVtbl->Base.Base.CreateRadialGradientBrush((ID2D1RenderTarget *)This, radialGradientBrushProperties, brushProperties, gradientStopCollection, radialGradientBrush))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateRadialGradientBrush")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateCompatibleRenderTarget(This, desiredSize, desiredPixelSize, desiredFormat, options, bitmapRenderTarget) \
|
||||
((This)->lpVtbl->Base.Base.CreateCompatibleRenderTarget((ID2D1RenderTarget *)This, desiredSize, desiredPixelSize, desiredFormat, options, bitmapRenderTarget))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateCompatibleRenderTarget")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateLayer(This, size, layer) \
|
||||
((This)->lpVtbl->Base.Base.CreateLayer((ID2D1RenderTarget *)This, size, layer))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateLayer")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateMesh(This, mesh) \
|
||||
((This)->lpVtbl->Base.Base.CreateMesh((ID2D1RenderTarget *)This, mesh))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateMesh")
|
||||
|
||||
#define ID2D1DeviceContext1_DrawLine(This, point0, point1, brush, strokeWidth, strokeStyle) \
|
||||
((This)->lpVtbl->Base.Base.DrawLine((ID2D1RenderTarget *)This, point0, point1, brush, strokeWidth, strokeStyle))
|
||||
#pragma deprecated("ID2D1DeviceContext1_DrawLine")
|
||||
|
||||
#define ID2D1DeviceContext1_DrawRectangle(This, rect, brush, strokeWidth, strokeStyle) \
|
||||
((This)->lpVtbl->Base.Base.DrawRectangle((ID2D1RenderTarget *)This, rect, brush, strokeWidth, strokeStyle))
|
||||
#pragma deprecated("ID2D1DeviceContext1_DrawRectangle")
|
||||
|
||||
#define ID2D1DeviceContext1_FillRectangle(This, rect, brush) \
|
||||
((This)->lpVtbl->Base.Base.FillRectangle((ID2D1RenderTarget *)This, rect, brush))
|
||||
#pragma deprecated("ID2D1DeviceContext1_FillRectangle")
|
||||
|
||||
#define ID2D1DeviceContext1_DrawRoundedRectangle(This, roundedRect, brush, strokeWidth, strokeStyle) \
|
||||
((This)->lpVtbl->Base.Base.DrawRoundedRectangle((ID2D1RenderTarget *)This, roundedRect, brush, strokeWidth, strokeStyle))
|
||||
#pragma deprecated("ID2D1DeviceContext1_DrawRoundedRectangle")
|
||||
|
||||
#define ID2D1DeviceContext1_FillRoundedRectangle(This, roundedRect, brush) \
|
||||
((This)->lpVtbl->Base.Base.FillRoundedRectangle((ID2D1RenderTarget *)This, roundedRect, brush))
|
||||
#pragma deprecated("ID2D1DeviceContext1_FillRoundedRectangle")
|
||||
|
||||
#define ID2D1DeviceContext1_DrawEllipse(This, ellipse, brush, strokeWidth, strokeStyle) \
|
||||
((This)->lpVtbl->Base.Base.DrawEllipse((ID2D1RenderTarget *)This, ellipse, brush, strokeWidth, strokeStyle))
|
||||
#pragma deprecated("ID2D1DeviceContext1_DrawEllipse")
|
||||
|
||||
#define ID2D1DeviceContext1_FillEllipse(This, ellipse, brush) \
|
||||
((This)->lpVtbl->Base.Base.FillEllipse((ID2D1RenderTarget *)This, ellipse, brush))
|
||||
#pragma deprecated("ID2D1DeviceContext1_FillEllipse")
|
||||
|
||||
#define ID2D1DeviceContext1_DrawGeometry(This, geometry, brush, strokeWidth, strokeStyle) \
|
||||
((This)->lpVtbl->Base.Base.DrawGeometry((ID2D1RenderTarget *)This, geometry, brush, strokeWidth, strokeStyle))
|
||||
#pragma deprecated("ID2D1DeviceContext1_DrawGeometry")
|
||||
|
||||
#define ID2D1DeviceContext1_FillGeometry(This, geometry, brush, opacityBrush) \
|
||||
((This)->lpVtbl->Base.Base.FillGeometry((ID2D1RenderTarget *)This, geometry, brush, opacityBrush))
|
||||
#pragma deprecated("ID2D1DeviceContext1_FillGeometry")
|
||||
|
||||
#define ID2D1DeviceContext1_FillMesh(This, mesh, brush) \
|
||||
((This)->lpVtbl->Base.Base.FillMesh((ID2D1RenderTarget *)This, mesh, brush))
|
||||
#pragma deprecated("ID2D1DeviceContext1_FillMesh")
|
||||
|
||||
#define ID2D1DeviceContext1_DrawText(This, string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode) \
|
||||
((This)->lpVtbl->Base.Base.DrawText((ID2D1RenderTarget *)This, string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode))
|
||||
#pragma deprecated("ID2D1DeviceContext1_DrawText")
|
||||
|
||||
#define ID2D1DeviceContext1_DrawTextLayout(This, origin, textLayout, defaultForegroundBrush, options) \
|
||||
((This)->lpVtbl->Base.Base.DrawTextLayout((ID2D1RenderTarget *)This, origin, textLayout, defaultForegroundBrush, options))
|
||||
#pragma deprecated("ID2D1DeviceContext1_DrawTextLayout")
|
||||
|
||||
#define ID2D1DeviceContext1_SetTransform(This, transform) \
|
||||
((This)->lpVtbl->Base.Base.SetTransform((ID2D1RenderTarget *)This, transform))
|
||||
#pragma deprecated("ID2D1DeviceContext1_SetTransform")
|
||||
|
||||
#define ID2D1DeviceContext1_GetTransform(This, transform) \
|
||||
((This)->lpVtbl->Base.Base.GetTransform((ID2D1RenderTarget *)This, transform))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetTransform")
|
||||
|
||||
#define ID2D1DeviceContext1_SetAntialiasMode(This, antialiasMode) \
|
||||
((This)->lpVtbl->Base.Base.SetAntialiasMode((ID2D1RenderTarget *)This, antialiasMode))
|
||||
#pragma deprecated("ID2D1DeviceContext1_SetAntialiasMode")
|
||||
|
||||
#define ID2D1DeviceContext1_GetAntialiasMode(This) \
|
||||
((This)->lpVtbl->Base.Base.GetAntialiasMode((ID2D1RenderTarget *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetAntialiasMode")
|
||||
|
||||
#define ID2D1DeviceContext1_SetTextAntialiasMode(This, textAntialiasMode) \
|
||||
((This)->lpVtbl->Base.Base.SetTextAntialiasMode((ID2D1RenderTarget *)This, textAntialiasMode))
|
||||
#pragma deprecated("ID2D1DeviceContext1_SetTextAntialiasMode")
|
||||
|
||||
#define ID2D1DeviceContext1_GetTextAntialiasMode(This) \
|
||||
((This)->lpVtbl->Base.Base.GetTextAntialiasMode((ID2D1RenderTarget *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetTextAntialiasMode")
|
||||
|
||||
#define ID2D1DeviceContext1_SetTextRenderingParams(This, textRenderingParams) \
|
||||
((This)->lpVtbl->Base.Base.SetTextRenderingParams((ID2D1RenderTarget *)This, textRenderingParams))
|
||||
#pragma deprecated("ID2D1DeviceContext1_SetTextRenderingParams")
|
||||
|
||||
#define ID2D1DeviceContext1_GetTextRenderingParams(This, textRenderingParams) \
|
||||
((This)->lpVtbl->Base.Base.GetTextRenderingParams((ID2D1RenderTarget *)This, textRenderingParams))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetTextRenderingParams")
|
||||
|
||||
#define ID2D1DeviceContext1_SetTags(This, tag1, tag2) \
|
||||
((This)->lpVtbl->Base.Base.SetTags((ID2D1RenderTarget *)This, tag1, tag2))
|
||||
#pragma deprecated("ID2D1DeviceContext1_SetTags")
|
||||
|
||||
#define ID2D1DeviceContext1_GetTags(This, tag1, tag2) \
|
||||
((This)->lpVtbl->Base.Base.GetTags((ID2D1RenderTarget *)This, tag1, tag2))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetTags")
|
||||
|
||||
#define ID2D1DeviceContext1_PopLayer(This) \
|
||||
((This)->lpVtbl->Base.Base.PopLayer((ID2D1RenderTarget *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_PopLayer")
|
||||
|
||||
#define ID2D1DeviceContext1_Flush(This, tag1, tag2) \
|
||||
((This)->lpVtbl->Base.Base.Flush((ID2D1RenderTarget *)This, tag1, tag2))
|
||||
#pragma deprecated("ID2D1DeviceContext1_Flush")
|
||||
|
||||
#define ID2D1DeviceContext1_SaveDrawingState(This, drawingStateBlock) \
|
||||
((This)->lpVtbl->Base.Base.SaveDrawingState((ID2D1RenderTarget *)This, drawingStateBlock))
|
||||
#pragma deprecated("ID2D1DeviceContext1_SaveDrawingState")
|
||||
|
||||
#define ID2D1DeviceContext1_RestoreDrawingState(This, drawingStateBlock) \
|
||||
((This)->lpVtbl->Base.Base.RestoreDrawingState((ID2D1RenderTarget *)This, drawingStateBlock))
|
||||
#pragma deprecated("ID2D1DeviceContext1_RestoreDrawingState")
|
||||
|
||||
#define ID2D1DeviceContext1_PushAxisAlignedClip(This, clipRect, antialiasMode) \
|
||||
((This)->lpVtbl->Base.Base.PushAxisAlignedClip((ID2D1RenderTarget *)This, clipRect, antialiasMode))
|
||||
#pragma deprecated("ID2D1DeviceContext1_PushAxisAlignedClip")
|
||||
|
||||
#define ID2D1DeviceContext1_PopAxisAlignedClip(This) \
|
||||
((This)->lpVtbl->Base.Base.PopAxisAlignedClip((ID2D1RenderTarget *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_PopAxisAlignedClip")
|
||||
|
||||
#define ID2D1DeviceContext1_Clear(This, clearColor) \
|
||||
((This)->lpVtbl->Base.Base.Clear((ID2D1RenderTarget *)This, clearColor))
|
||||
#pragma deprecated("ID2D1DeviceContext1_Clear")
|
||||
|
||||
#define ID2D1DeviceContext1_BeginDraw(This) \
|
||||
((This)->lpVtbl->Base.Base.BeginDraw((ID2D1RenderTarget *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_BeginDraw")
|
||||
|
||||
#define ID2D1DeviceContext1_EndDraw(This, tag1, tag2) \
|
||||
((This)->lpVtbl->Base.Base.EndDraw((ID2D1RenderTarget *)This, tag1, tag2))
|
||||
#pragma deprecated("ID2D1DeviceContext1_EndDraw")
|
||||
|
||||
#define ID2D1DeviceContext1_GetPixelFormat(This) \
|
||||
((This)->lpVtbl->Base.Base.GetPixelFormat((ID2D1RenderTarget *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetPixelFormat")
|
||||
|
||||
#define ID2D1DeviceContext1_SetDpi(This, dpiX, dpiY) \
|
||||
((This)->lpVtbl->Base.Base.SetDpi((ID2D1RenderTarget *)This, dpiX, dpiY))
|
||||
#pragma deprecated("ID2D1DeviceContext1_SetDpi")
|
||||
|
||||
#define ID2D1DeviceContext1_GetDpi(This, dpiX, dpiY) \
|
||||
((This)->lpVtbl->Base.Base.GetDpi((ID2D1RenderTarget *)This, dpiX, dpiY))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetDpi")
|
||||
|
||||
#define ID2D1DeviceContext1_GetSize(This) \
|
||||
((This)->lpVtbl->Base.Base.GetSize((ID2D1RenderTarget *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetSize")
|
||||
|
||||
#define ID2D1DeviceContext1_GetPixelSize(This) \
|
||||
((This)->lpVtbl->Base.Base.GetPixelSize((ID2D1RenderTarget *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetPixelSize")
|
||||
|
||||
#define ID2D1DeviceContext1_GetMaximumBitmapSize(This) \
|
||||
((This)->lpVtbl->Base.Base.GetMaximumBitmapSize((ID2D1RenderTarget *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetMaximumBitmapSize")
|
||||
|
||||
#define ID2D1DeviceContext1_IsSupported(This, renderTargetProperties) \
|
||||
((This)->lpVtbl->Base.Base.IsSupported((ID2D1RenderTarget *)This, renderTargetProperties))
|
||||
#pragma deprecated("ID2D1DeviceContext1_IsSupported")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateBitmap(This, size, sourceData, pitch, bitmapProperties, bitmap) \
|
||||
((This)->lpVtbl->Base.CreateBitmap((ID2D1DeviceContext *)This, size, sourceData, pitch, bitmapProperties, bitmap))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateBitmap")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateBitmapFromWicBitmap(This, wicBitmapSource, bitmapProperties, bitmap) \
|
||||
((This)->lpVtbl->Base.CreateBitmapFromWicBitmap((ID2D1DeviceContext *)This, wicBitmapSource, bitmapProperties, bitmap))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateBitmapFromWicBitmap")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateColorContext(This, space, profile, profileSize, colorContext) \
|
||||
((This)->lpVtbl->Base.CreateColorContext((ID2D1DeviceContext *)This, space, profile, profileSize, colorContext))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateColorContext")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateColorContextFromFilename(This, filename, colorContext) \
|
||||
((This)->lpVtbl->Base.CreateColorContextFromFilename((ID2D1DeviceContext *)This, filename, colorContext))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateColorContextFromFilename")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateColorContextFromWicColorContext(This, wicColorContext, colorContext) \
|
||||
((This)->lpVtbl->Base.CreateColorContextFromWicColorContext((ID2D1DeviceContext *)This, wicColorContext, colorContext))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateColorContextFromWicColorContext")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateBitmapFromDxgiSurface(This, surface, bitmapProperties, bitmap) \
|
||||
((This)->lpVtbl->Base.CreateBitmapFromDxgiSurface((ID2D1DeviceContext *)This, surface, bitmapProperties, bitmap))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateBitmapFromDxgiSurface")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateEffect(This, effectId, effect) \
|
||||
((This)->lpVtbl->Base.CreateEffect((ID2D1DeviceContext *)This, effectId, effect))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateEffect")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateGradientStopCollection(This, straightAlphaGradientStops, straightAlphaGradientStopsCount, preInterpolationSpace, postInterpolationSpace, bufferPrecision, extendMode, colorInterpolationMode, gradientStopCollection1) \
|
||||
((This)->lpVtbl->Base.CreateGradientStopCollection((ID2D1DeviceContext *)This, straightAlphaGradientStops, straightAlphaGradientStopsCount, preInterpolationSpace, postInterpolationSpace, bufferPrecision, extendMode, colorInterpolationMode, gradientStopCollection1))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateGradientStopCollection")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateImageBrush(This, image, imageBrushProperties, brushProperties, imageBrush) \
|
||||
((This)->lpVtbl->Base.CreateImageBrush((ID2D1DeviceContext *)This, image, imageBrushProperties, brushProperties, imageBrush))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateImageBrush")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateBitmapBrush(This, bitmap, bitmapBrushProperties, brushProperties, bitmapBrush) \
|
||||
((This)->lpVtbl->Base.CreateBitmapBrush((ID2D1DeviceContext *)This, bitmap, bitmapBrushProperties, brushProperties, bitmapBrush))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateBitmapBrush")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateCommandList(This, commandList) \
|
||||
((This)->lpVtbl->Base.CreateCommandList((ID2D1DeviceContext *)This, commandList))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateCommandList")
|
||||
|
||||
#define ID2D1DeviceContext1_IsDxgiFormatSupported(This, format) \
|
||||
((This)->lpVtbl->Base.IsDxgiFormatSupported((ID2D1DeviceContext *)This, format))
|
||||
#pragma deprecated("ID2D1DeviceContext1_IsDxgiFormatSupported")
|
||||
|
||||
#define ID2D1DeviceContext1_IsBufferPrecisionSupported(This, bufferPrecision) \
|
||||
((This)->lpVtbl->Base.IsBufferPrecisionSupported((ID2D1DeviceContext *)This, bufferPrecision))
|
||||
#pragma deprecated("ID2D1DeviceContext1_IsBufferPrecisionSupported")
|
||||
|
||||
#define ID2D1DeviceContext1_GetImageLocalBounds(This, image, localBounds) \
|
||||
((This)->lpVtbl->Base.GetImageLocalBounds((ID2D1DeviceContext *)This, image, localBounds))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetImageLocalBounds")
|
||||
|
||||
#define ID2D1DeviceContext1_GetImageWorldBounds(This, image, worldBounds) \
|
||||
((This)->lpVtbl->Base.GetImageWorldBounds((ID2D1DeviceContext *)This, image, worldBounds))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetImageWorldBounds")
|
||||
|
||||
#define ID2D1DeviceContext1_GetGlyphRunWorldBounds(This, baselineOrigin, glyphRun, measuringMode, bounds) \
|
||||
((This)->lpVtbl->Base.GetGlyphRunWorldBounds((ID2D1DeviceContext *)This, baselineOrigin, glyphRun, measuringMode, bounds))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetGlyphRunWorldBounds")
|
||||
|
||||
#define ID2D1DeviceContext1_GetDevice(This, device) \
|
||||
((This)->lpVtbl->Base.GetDevice((ID2D1DeviceContext *)This, device))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetDevice")
|
||||
|
||||
#define ID2D1DeviceContext1_SetTarget(This, image) \
|
||||
((This)->lpVtbl->Base.SetTarget((ID2D1DeviceContext *)This, image))
|
||||
#pragma deprecated("ID2D1DeviceContext1_SetTarget")
|
||||
|
||||
#define ID2D1DeviceContext1_GetTarget(This, image) \
|
||||
((This)->lpVtbl->Base.GetTarget((ID2D1DeviceContext *)This, image))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetTarget")
|
||||
|
||||
#define ID2D1DeviceContext1_SetRenderingControls(This, renderingControls) \
|
||||
((This)->lpVtbl->Base.SetRenderingControls((ID2D1DeviceContext *)This, renderingControls))
|
||||
#pragma deprecated("ID2D1DeviceContext1_SetRenderingControls")
|
||||
|
||||
#define ID2D1DeviceContext1_GetRenderingControls(This, renderingControls) \
|
||||
((This)->lpVtbl->Base.GetRenderingControls((ID2D1DeviceContext *)This, renderingControls))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetRenderingControls")
|
||||
|
||||
#define ID2D1DeviceContext1_SetPrimitiveBlend(This, primitiveBlend) \
|
||||
((This)->lpVtbl->Base.SetPrimitiveBlend((ID2D1DeviceContext *)This, primitiveBlend))
|
||||
#pragma deprecated("ID2D1DeviceContext1_SetPrimitiveBlend")
|
||||
|
||||
#define ID2D1DeviceContext1_GetPrimitiveBlend(This) \
|
||||
((This)->lpVtbl->Base.GetPrimitiveBlend((ID2D1DeviceContext *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetPrimitiveBlend")
|
||||
|
||||
#define ID2D1DeviceContext1_SetUnitMode(This, unitMode) \
|
||||
((This)->lpVtbl->Base.SetUnitMode((ID2D1DeviceContext *)This, unitMode))
|
||||
#pragma deprecated("ID2D1DeviceContext1_SetUnitMode")
|
||||
|
||||
#define ID2D1DeviceContext1_GetUnitMode(This) \
|
||||
((This)->lpVtbl->Base.GetUnitMode((ID2D1DeviceContext *)This))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetUnitMode")
|
||||
|
||||
#define ID2D1DeviceContext1_DrawGlyphRun(This, baselineOrigin, glyphRun, glyphRunDescription, foregroundBrush, measuringMode) \
|
||||
((This)->lpVtbl->Base.DrawGlyphRun((ID2D1DeviceContext *)This, baselineOrigin, glyphRun, glyphRunDescription, foregroundBrush, measuringMode))
|
||||
#pragma deprecated("ID2D1DeviceContext1_DrawGlyphRun")
|
||||
|
||||
#define ID2D1DeviceContext1_DrawImage(This, image, targetOffset, imageRectangle, interpolationMode, compositeMode) \
|
||||
((This)->lpVtbl->Base.DrawImage((ID2D1DeviceContext *)This, image, targetOffset, imageRectangle, interpolationMode, compositeMode))
|
||||
#pragma deprecated("ID2D1DeviceContext1_DrawImage")
|
||||
|
||||
#define ID2D1DeviceContext1_DrawGdiMetafile(This, gdiMetafile, targetOffset) \
|
||||
((This)->lpVtbl->Base.DrawGdiMetafile((ID2D1DeviceContext *)This, gdiMetafile, targetOffset))
|
||||
#pragma deprecated("ID2D1DeviceContext1_DrawGdiMetafile")
|
||||
|
||||
#define ID2D1DeviceContext1_DrawBitmap(This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle, perspectiveTransform) \
|
||||
((This)->lpVtbl->Base.DrawBitmap((ID2D1DeviceContext *)This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle, perspectiveTransform))
|
||||
#pragma deprecated("ID2D1DeviceContext1_DrawBitmap")
|
||||
|
||||
#define ID2D1DeviceContext1_PushLayer(This, layerParameters, layer) \
|
||||
((This)->lpVtbl->Base.PushLayer((ID2D1DeviceContext *)This, layerParameters, layer))
|
||||
#pragma deprecated("ID2D1DeviceContext1_PushLayer")
|
||||
|
||||
#define ID2D1DeviceContext1_InvalidateEffectInputRectangle(This, effect, input, inputRectangle) \
|
||||
((This)->lpVtbl->Base.InvalidateEffectInputRectangle((ID2D1DeviceContext *)This, effect, input, inputRectangle))
|
||||
#pragma deprecated("ID2D1DeviceContext1_InvalidateEffectInputRectangle")
|
||||
|
||||
#define ID2D1DeviceContext1_GetEffectInvalidRectangleCount(This, effect, rectangleCount) \
|
||||
((This)->lpVtbl->Base.GetEffectInvalidRectangleCount((ID2D1DeviceContext *)This, effect, rectangleCount))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetEffectInvalidRectangleCount")
|
||||
|
||||
#define ID2D1DeviceContext1_GetEffectInvalidRectangles(This, effect, rectangles, rectanglesCount) \
|
||||
((This)->lpVtbl->Base.GetEffectInvalidRectangles((ID2D1DeviceContext *)This, effect, rectangles, rectanglesCount))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetEffectInvalidRectangles")
|
||||
|
||||
#define ID2D1DeviceContext1_GetEffectRequiredInputRectangles(This, renderEffect, renderImageRectangle, inputDescriptions, requiredInputRects, inputCount) \
|
||||
((This)->lpVtbl->Base.GetEffectRequiredInputRectangles((ID2D1DeviceContext *)This, renderEffect, renderImageRectangle, inputDescriptions, requiredInputRects, inputCount))
|
||||
#pragma deprecated("ID2D1DeviceContext1_GetEffectRequiredInputRectangles")
|
||||
|
||||
#define ID2D1DeviceContext1_FillOpacityMask(This, opacityMask, brush, destinationRectangle, sourceRectangle) \
|
||||
((This)->lpVtbl->Base.FillOpacityMask((ID2D1DeviceContext *)This, opacityMask, brush, destinationRectangle, sourceRectangle))
|
||||
#pragma deprecated("ID2D1DeviceContext1_FillOpacityMask")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateFilledGeometryRealization(This, geometry, flatteningTolerance, geometryRealization) \
|
||||
((This)->lpVtbl->CreateFilledGeometryRealization(This, geometry, flatteningTolerance, geometryRealization))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateFilledGeometryRealization")
|
||||
|
||||
#define ID2D1DeviceContext1_CreateStrokedGeometryRealization(This, geometry, flatteningTolerance, strokeWidth, strokeStyle, geometryRealization) \
|
||||
((This)->lpVtbl->CreateStrokedGeometryRealization(This, geometry, flatteningTolerance, strokeWidth, strokeStyle, geometryRealization))
|
||||
#pragma deprecated("ID2D1DeviceContext1_CreateStrokedGeometryRealization")
|
||||
|
||||
#define ID2D1DeviceContext1_DrawGeometryRealization(This, geometryRealization, brush) \
|
||||
((This)->lpVtbl->DrawGeometryRealization(This, geometryRealization, brush))
|
||||
#pragma deprecated("ID2D1DeviceContext1_DrawGeometryRealization")
|
||||
|
||||
typedef interface ID2D1Device1 ID2D1Device1;
|
||||
|
||||
@@ -641,47 +550,36 @@ interface ID2D1Device1
|
||||
|
||||
#define ID2D1Device1_QueryInterface(This, riid, ppv) \
|
||||
((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv))
|
||||
#pragma deprecated("ID2D1Device1_QueryInterface")
|
||||
|
||||
#define ID2D1Device1_AddRef(This) \
|
||||
((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This))
|
||||
#pragma deprecated("ID2D1Device1_AddRef")
|
||||
|
||||
#define ID2D1Device1_Release(This) \
|
||||
((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This))
|
||||
#pragma deprecated("ID2D1Device1_Release")
|
||||
|
||||
#define ID2D1Device1_GetFactory(This, factory) \
|
||||
((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory))
|
||||
#pragma deprecated("ID2D1Device1_GetFactory")
|
||||
|
||||
#define ID2D1Device1_CreatePrintControl(This, wicFactory, documentTarget, printControlProperties, printControl) \
|
||||
((This)->lpVtbl->Base.CreatePrintControl((ID2D1Device *)This, wicFactory, documentTarget, printControlProperties, printControl))
|
||||
#pragma deprecated("ID2D1Device1_CreatePrintControl")
|
||||
|
||||
#define ID2D1Device1_SetMaximumTextureMemory(This, maximumInBytes) \
|
||||
((This)->lpVtbl->Base.SetMaximumTextureMemory((ID2D1Device *)This, maximumInBytes))
|
||||
#pragma deprecated("ID2D1Device1_SetMaximumTextureMemory")
|
||||
|
||||
#define ID2D1Device1_GetMaximumTextureMemory(This) \
|
||||
((This)->lpVtbl->Base.GetMaximumTextureMemory((ID2D1Device *)This))
|
||||
#pragma deprecated("ID2D1Device1_GetMaximumTextureMemory")
|
||||
|
||||
#define ID2D1Device1_ClearResources(This, millisecondsSinceUse) \
|
||||
((This)->lpVtbl->Base.ClearResources((ID2D1Device *)This, millisecondsSinceUse))
|
||||
#pragma deprecated("ID2D1Device1_ClearResources")
|
||||
|
||||
#define ID2D1Device1_GetRenderingPriority(This) \
|
||||
((This)->lpVtbl->GetRenderingPriority(This))
|
||||
#pragma deprecated("ID2D1Device1_GetRenderingPriority")
|
||||
|
||||
#define ID2D1Device1_SetRenderingPriority(This, renderingPriority) \
|
||||
((This)->lpVtbl->SetRenderingPriority(This, renderingPriority))
|
||||
#pragma deprecated("ID2D1Device1_SetRenderingPriority")
|
||||
|
||||
#define ID2D1Device1_CreateDeviceContext(This, options, deviceContext1) \
|
||||
((This)->lpVtbl->CreateDeviceContext(This, options, deviceContext1))
|
||||
#pragma deprecated("ID2D1Device1_CreateDeviceContext")
|
||||
|
||||
typedef interface ID2D1Factory2 ID2D1Factory2;
|
||||
|
||||
@@ -706,99 +604,75 @@ interface ID2D1Factory2
|
||||
|
||||
#define ID2D1Factory2_QueryInterface(This, riid, ppv) \
|
||||
((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv))
|
||||
#pragma deprecated("ID2D1Factory2_QueryInterface")
|
||||
|
||||
#define ID2D1Factory2_AddRef(This) \
|
||||
((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This))
|
||||
#pragma deprecated("ID2D1Factory2_AddRef")
|
||||
|
||||
#define ID2D1Factory2_Release(This) \
|
||||
((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This))
|
||||
#pragma deprecated("ID2D1Factory2_Release")
|
||||
|
||||
#define ID2D1Factory2_ReloadSystemMetrics(This) \
|
||||
((This)->lpVtbl->Base.Base.ReloadSystemMetrics((ID2D1Factory *)This))
|
||||
#pragma deprecated("ID2D1Factory2_ReloadSystemMetrics")
|
||||
|
||||
#define ID2D1Factory2_GetDesktopDpi(This, dpiX, dpiY) \
|
||||
((This)->lpVtbl->Base.Base.GetDesktopDpi((ID2D1Factory *)This, dpiX, dpiY))
|
||||
#pragma deprecated("ID2D1Factory2_GetDesktopDpi")
|
||||
|
||||
#define ID2D1Factory2_CreateRectangleGeometry(This, rectangle, rectangleGeometry) \
|
||||
((This)->lpVtbl->Base.Base.CreateRectangleGeometry((ID2D1Factory *)This, rectangle, rectangleGeometry))
|
||||
#pragma deprecated("ID2D1Factory2_CreateRectangleGeometry")
|
||||
|
||||
#define ID2D1Factory2_CreateRoundedRectangleGeometry(This, roundedRectangle, roundedRectangleGeometry) \
|
||||
((This)->lpVtbl->Base.Base.CreateRoundedRectangleGeometry((ID2D1Factory *)This, roundedRectangle, roundedRectangleGeometry))
|
||||
#pragma deprecated("ID2D1Factory2_CreateRoundedRectangleGeometry")
|
||||
|
||||
#define ID2D1Factory2_CreateEllipseGeometry(This, ellipse, ellipseGeometry) \
|
||||
((This)->lpVtbl->Base.Base.CreateEllipseGeometry((ID2D1Factory *)This, ellipse, ellipseGeometry))
|
||||
#pragma deprecated("ID2D1Factory2_CreateEllipseGeometry")
|
||||
|
||||
#define ID2D1Factory2_CreateGeometryGroup(This, fillMode, geometries, geometriesCount, geometryGroup) \
|
||||
((This)->lpVtbl->Base.Base.CreateGeometryGroup((ID2D1Factory *)This, fillMode, geometries, geometriesCount, geometryGroup))
|
||||
#pragma deprecated("ID2D1Factory2_CreateGeometryGroup")
|
||||
|
||||
#define ID2D1Factory2_CreateTransformedGeometry(This, sourceGeometry, transform, transformedGeometry) \
|
||||
((This)->lpVtbl->Base.Base.CreateTransformedGeometry((ID2D1Factory *)This, sourceGeometry, transform, transformedGeometry))
|
||||
#pragma deprecated("ID2D1Factory2_CreateTransformedGeometry")
|
||||
|
||||
#define ID2D1Factory2_CreateWicBitmapRenderTarget(This, target, renderTargetProperties, renderTarget) \
|
||||
((This)->lpVtbl->Base.Base.CreateWicBitmapRenderTarget((ID2D1Factory *)This, target, renderTargetProperties, renderTarget))
|
||||
#pragma deprecated("ID2D1Factory2_CreateWicBitmapRenderTarget")
|
||||
|
||||
#define ID2D1Factory2_CreateHwndRenderTarget(This, renderTargetProperties, hwndRenderTargetProperties, hwndRenderTarget) \
|
||||
((This)->lpVtbl->Base.Base.CreateHwndRenderTarget((ID2D1Factory *)This, renderTargetProperties, hwndRenderTargetProperties, hwndRenderTarget))
|
||||
#pragma deprecated("ID2D1Factory2_CreateHwndRenderTarget")
|
||||
|
||||
#define ID2D1Factory2_CreateDxgiSurfaceRenderTarget(This, dxgiSurface, renderTargetProperties, renderTarget) \
|
||||
((This)->lpVtbl->Base.Base.CreateDxgiSurfaceRenderTarget((ID2D1Factory *)This, dxgiSurface, renderTargetProperties, renderTarget))
|
||||
#pragma deprecated("ID2D1Factory2_CreateDxgiSurfaceRenderTarget")
|
||||
|
||||
#define ID2D1Factory2_CreateDCRenderTarget(This, renderTargetProperties, dcRenderTarget) \
|
||||
((This)->lpVtbl->Base.Base.CreateDCRenderTarget((ID2D1Factory *)This, renderTargetProperties, dcRenderTarget))
|
||||
#pragma deprecated("ID2D1Factory2_CreateDCRenderTarget")
|
||||
|
||||
#define ID2D1Factory2_CreateStrokeStyle(This, strokeStyleProperties, dashes, dashesCount, strokeStyle) \
|
||||
((This)->lpVtbl->Base.CreateStrokeStyle((ID2D1Factory1 *)This, strokeStyleProperties, dashes, dashesCount, strokeStyle))
|
||||
#pragma deprecated("ID2D1Factory2_CreateStrokeStyle")
|
||||
|
||||
#define ID2D1Factory2_CreatePathGeometry(This, pathGeometry) \
|
||||
((This)->lpVtbl->Base.CreatePathGeometry((ID2D1Factory1 *)This, pathGeometry))
|
||||
#pragma deprecated("ID2D1Factory2_CreatePathGeometry")
|
||||
|
||||
#define ID2D1Factory2_CreateDrawingStateBlock(This, drawingStateDescription, textRenderingParams, drawingStateBlock) \
|
||||
((This)->lpVtbl->Base.CreateDrawingStateBlock((ID2D1Factory1 *)This, drawingStateDescription, textRenderingParams, drawingStateBlock))
|
||||
#pragma deprecated("ID2D1Factory2_CreateDrawingStateBlock")
|
||||
|
||||
#define ID2D1Factory2_CreateGdiMetafile(This, metafileStream, metafile) \
|
||||
((This)->lpVtbl->Base.CreateGdiMetafile((ID2D1Factory1 *)This, metafileStream, metafile))
|
||||
#pragma deprecated("ID2D1Factory2_CreateGdiMetafile")
|
||||
|
||||
#define ID2D1Factory2_RegisterEffectFromStream(This, classId, propertyXml, bindings, bindingsCount, effectFactory) \
|
||||
((This)->lpVtbl->Base.RegisterEffectFromStream((ID2D1Factory1 *)This, classId, propertyXml, bindings, bindingsCount, effectFactory))
|
||||
#pragma deprecated("ID2D1Factory2_RegisterEffectFromStream")
|
||||
|
||||
#define ID2D1Factory2_RegisterEffectFromString(This, classId, propertyXml, bindings, bindingsCount, effectFactory) \
|
||||
((This)->lpVtbl->Base.RegisterEffectFromString((ID2D1Factory1 *)This, classId, propertyXml, bindings, bindingsCount, effectFactory))
|
||||
#pragma deprecated("ID2D1Factory2_RegisterEffectFromString")
|
||||
|
||||
#define ID2D1Factory2_UnregisterEffect(This, classId) \
|
||||
((This)->lpVtbl->Base.UnregisterEffect((ID2D1Factory1 *)This, classId))
|
||||
#pragma deprecated("ID2D1Factory2_UnregisterEffect")
|
||||
|
||||
#define ID2D1Factory2_GetRegisteredEffects(This, effects, effectsCount, effectsReturned, effectsRegistered) \
|
||||
((This)->lpVtbl->Base.GetRegisteredEffects((ID2D1Factory1 *)This, effects, effectsCount, effectsReturned, effectsRegistered))
|
||||
#pragma deprecated("ID2D1Factory2_GetRegisteredEffects")
|
||||
|
||||
#define ID2D1Factory2_GetEffectProperties(This, effectId, properties) \
|
||||
((This)->lpVtbl->Base.GetEffectProperties((ID2D1Factory1 *)This, effectId, properties))
|
||||
#pragma deprecated("ID2D1Factory2_GetEffectProperties")
|
||||
|
||||
#define ID2D1Factory2_CreateDevice(This, dxgiDevice, d2dDevice1) \
|
||||
((This)->lpVtbl->CreateDevice(This, dxgiDevice, d2dDevice1))
|
||||
#pragma deprecated("ID2D1Factory2_CreateDevice")
|
||||
|
||||
typedef interface ID2D1CommandSink1 ID2D1CommandSink1;
|
||||
|
||||
@@ -822,119 +696,90 @@ interface ID2D1CommandSink1
|
||||
|
||||
#define ID2D1CommandSink1_QueryInterface(This, riid, ppv) \
|
||||
((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv))
|
||||
#pragma deprecated("ID2D1CommandSink1_QueryInterface")
|
||||
|
||||
#define ID2D1CommandSink1_AddRef(This) \
|
||||
((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This))
|
||||
#pragma deprecated("ID2D1CommandSink1_AddRef")
|
||||
|
||||
#define ID2D1CommandSink1_Release(This) \
|
||||
((This)->lpVtbl->Base.Base.Release((IUnknown *)This))
|
||||
#pragma deprecated("ID2D1CommandSink1_Release")
|
||||
|
||||
#define ID2D1CommandSink1_BeginDraw(This) \
|
||||
((This)->lpVtbl->Base.BeginDraw((ID2D1CommandSink *)This))
|
||||
#pragma deprecated("ID2D1CommandSink1_BeginDraw")
|
||||
|
||||
#define ID2D1CommandSink1_EndDraw(This) \
|
||||
((This)->lpVtbl->Base.EndDraw((ID2D1CommandSink *)This))
|
||||
#pragma deprecated("ID2D1CommandSink1_EndDraw")
|
||||
|
||||
#define ID2D1CommandSink1_SetAntialiasMode(This, antialiasMode) \
|
||||
((This)->lpVtbl->Base.SetAntialiasMode((ID2D1CommandSink *)This, antialiasMode))
|
||||
#pragma deprecated("ID2D1CommandSink1_SetAntialiasMode")
|
||||
|
||||
#define ID2D1CommandSink1_SetTags(This, tag1, tag2) \
|
||||
((This)->lpVtbl->Base.SetTags((ID2D1CommandSink *)This, tag1, tag2))
|
||||
#pragma deprecated("ID2D1CommandSink1_SetTags")
|
||||
|
||||
#define ID2D1CommandSink1_SetTextAntialiasMode(This, textAntialiasMode) \
|
||||
((This)->lpVtbl->Base.SetTextAntialiasMode((ID2D1CommandSink *)This, textAntialiasMode))
|
||||
#pragma deprecated("ID2D1CommandSink1_SetTextAntialiasMode")
|
||||
|
||||
#define ID2D1CommandSink1_SetTextRenderingParams(This, textRenderingParams) \
|
||||
((This)->lpVtbl->Base.SetTextRenderingParams((ID2D1CommandSink *)This, textRenderingParams))
|
||||
#pragma deprecated("ID2D1CommandSink1_SetTextRenderingParams")
|
||||
|
||||
#define ID2D1CommandSink1_SetTransform(This, transform) \
|
||||
((This)->lpVtbl->Base.SetTransform((ID2D1CommandSink *)This, transform))
|
||||
#pragma deprecated("ID2D1CommandSink1_SetTransform")
|
||||
|
||||
#define ID2D1CommandSink1_SetPrimitiveBlend(This, primitiveBlend) \
|
||||
((This)->lpVtbl->Base.SetPrimitiveBlend((ID2D1CommandSink *)This, primitiveBlend))
|
||||
#pragma deprecated("ID2D1CommandSink1_SetPrimitiveBlend")
|
||||
|
||||
#define ID2D1CommandSink1_SetUnitMode(This, unitMode) \
|
||||
((This)->lpVtbl->Base.SetUnitMode((ID2D1CommandSink *)This, unitMode))
|
||||
#pragma deprecated("ID2D1CommandSink1_SetUnitMode")
|
||||
|
||||
#define ID2D1CommandSink1_Clear(This, color) \
|
||||
((This)->lpVtbl->Base.Clear((ID2D1CommandSink *)This, color))
|
||||
#pragma deprecated("ID2D1CommandSink1_Clear")
|
||||
|
||||
#define ID2D1CommandSink1_DrawGlyphRun(This, baselineOrigin, glyphRun, glyphRunDescription, foregroundBrush, measuringMode) \
|
||||
((This)->lpVtbl->Base.DrawGlyphRun((ID2D1CommandSink *)This, baselineOrigin, glyphRun, glyphRunDescription, foregroundBrush, measuringMode))
|
||||
#pragma deprecated("ID2D1CommandSink1_DrawGlyphRun")
|
||||
|
||||
#define ID2D1CommandSink1_DrawLine(This, point0, point1, brush, strokeWidth, strokeStyle) \
|
||||
((This)->lpVtbl->Base.DrawLine((ID2D1CommandSink *)This, point0, point1, brush, strokeWidth, strokeStyle))
|
||||
#pragma deprecated("ID2D1CommandSink1_DrawLine")
|
||||
|
||||
#define ID2D1CommandSink1_DrawGeometry(This, geometry, brush, strokeWidth, strokeStyle) \
|
||||
((This)->lpVtbl->Base.DrawGeometry((ID2D1CommandSink *)This, geometry, brush, strokeWidth, strokeStyle))
|
||||
#pragma deprecated("ID2D1CommandSink1_DrawGeometry")
|
||||
|
||||
#define ID2D1CommandSink1_DrawRectangle(This, rect, brush, strokeWidth, strokeStyle) \
|
||||
((This)->lpVtbl->Base.DrawRectangle((ID2D1CommandSink *)This, rect, brush, strokeWidth, strokeStyle))
|
||||
#pragma deprecated("ID2D1CommandSink1_DrawRectangle")
|
||||
|
||||
#define ID2D1CommandSink1_DrawBitmap(This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle, perspectiveTransform) \
|
||||
((This)->lpVtbl->Base.DrawBitmap((ID2D1CommandSink *)This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle, perspectiveTransform))
|
||||
#pragma deprecated("ID2D1CommandSink1_DrawBitmap")
|
||||
|
||||
#define ID2D1CommandSink1_DrawImage(This, image, targetOffset, imageRectangle, interpolationMode, compositeMode) \
|
||||
((This)->lpVtbl->Base.DrawImage((ID2D1CommandSink *)This, image, targetOffset, imageRectangle, interpolationMode, compositeMode))
|
||||
#pragma deprecated("ID2D1CommandSink1_DrawImage")
|
||||
|
||||
#define ID2D1CommandSink1_DrawGdiMetafile(This, gdiMetafile, targetOffset) \
|
||||
((This)->lpVtbl->Base.DrawGdiMetafile((ID2D1CommandSink *)This, gdiMetafile, targetOffset))
|
||||
#pragma deprecated("ID2D1CommandSink1_DrawGdiMetafile")
|
||||
|
||||
#define ID2D1CommandSink1_FillMesh(This, mesh, brush) \
|
||||
((This)->lpVtbl->Base.FillMesh((ID2D1CommandSink *)This, mesh, brush))
|
||||
#pragma deprecated("ID2D1CommandSink1_FillMesh")
|
||||
|
||||
#define ID2D1CommandSink1_FillOpacityMask(This, opacityMask, brush, destinationRectangle, sourceRectangle) \
|
||||
((This)->lpVtbl->Base.FillOpacityMask((ID2D1CommandSink *)This, opacityMask, brush, destinationRectangle, sourceRectangle))
|
||||
#pragma deprecated("ID2D1CommandSink1_FillOpacityMask")
|
||||
|
||||
#define ID2D1CommandSink1_FillGeometry(This, geometry, brush, opacityBrush) \
|
||||
((This)->lpVtbl->Base.FillGeometry((ID2D1CommandSink *)This, geometry, brush, opacityBrush))
|
||||
#pragma deprecated("ID2D1CommandSink1_FillGeometry")
|
||||
|
||||
#define ID2D1CommandSink1_FillRectangle(This, rect, brush) \
|
||||
((This)->lpVtbl->Base.FillRectangle((ID2D1CommandSink *)This, rect, brush))
|
||||
#pragma deprecated("ID2D1CommandSink1_FillRectangle")
|
||||
|
||||
#define ID2D1CommandSink1_PushAxisAlignedClip(This, clipRect, antialiasMode) \
|
||||
((This)->lpVtbl->Base.PushAxisAlignedClip((ID2D1CommandSink *)This, clipRect, antialiasMode))
|
||||
#pragma deprecated("ID2D1CommandSink1_PushAxisAlignedClip")
|
||||
|
||||
#define ID2D1CommandSink1_PushLayer(This, layerParameters1, layer) \
|
||||
((This)->lpVtbl->Base.PushLayer((ID2D1CommandSink *)This, layerParameters1, layer))
|
||||
#pragma deprecated("ID2D1CommandSink1_PushLayer")
|
||||
|
||||
#define ID2D1CommandSink1_PopAxisAlignedClip(This) \
|
||||
((This)->lpVtbl->Base.PopAxisAlignedClip((ID2D1CommandSink *)This))
|
||||
#pragma deprecated("ID2D1CommandSink1_PopAxisAlignedClip")
|
||||
|
||||
#define ID2D1CommandSink1_PopLayer(This) \
|
||||
((This)->lpVtbl->Base.PopLayer((ID2D1CommandSink *)This))
|
||||
#pragma deprecated("ID2D1CommandSink1_PopLayer")
|
||||
|
||||
#define ID2D1CommandSink1_SetPrimitiveBlend1(This, primitiveBlend) \
|
||||
((This)->lpVtbl->SetPrimitiveBlend1(This, primitiveBlend))
|
||||
#pragma deprecated("ID2D1CommandSink1_SetPrimitiveBlend1")
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -215,16 +215,6 @@ namespace D2D1
|
||||
|
||||
return inkStyleProperties;
|
||||
}
|
||||
|
||||
COM_DECLSPEC_NOTHROW
|
||||
D2D1FORCEINLINE
|
||||
D2D1_RECT_U
|
||||
InfiniteRectU()
|
||||
{
|
||||
D2D1_RECT_U rect = { 0u, 0u, UINT_MAX, UINT_MAX };
|
||||
|
||||
return rect;
|
||||
}
|
||||
} // namespace D2D1
|
||||
|
||||
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */
|
||||
|
||||
@@ -9661,8 +9661,6 @@ DEFINE_GUID(D3D11_DECODER_PROFILE_MPEG4PT2_VLD_ADVSIMPLE_NOGMC, 0xed418a9f, 0x0
|
||||
DEFINE_GUID(D3D11_DECODER_PROFILE_MPEG4PT2_VLD_ADVSIMPLE_GMC, 0xab998b5b, 0x4258,0x44a9,0x9f,0xeb,0x94,0xe5,0x97,0xa6,0xba,0xae);
|
||||
DEFINE_GUID(D3D11_DECODER_PROFILE_HEVC_VLD_MAIN, 0x5b11d51b, 0x2f4c,0x4452,0xbc,0xc3,0x09,0xf2,0xa1,0x16,0x0c,0xc0);
|
||||
DEFINE_GUID(D3D11_DECODER_PROFILE_HEVC_VLD_MAIN10, 0x107af0e0, 0xef1a,0x4d19,0xab,0xa8,0x67,0xa1,0x63,0x07,0x3d,0x13);
|
||||
DEFINE_GUID(D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0, 0x463707f8, 0xa1d0, 0x4585, 0x87, 0x6d, 0x83, 0xaa, 0x6d, 0x60, 0xb8, 0x9e);
|
||||
DEFINE_GUID(D3D11_DECODER_PROFILE_VP8_VLD, 0x90b899ea, 0x3a62, 0x4705, 0x88, 0xb3, 0x8d, 0xf0, 0x4b, 0x27, 0x44, 0xe7);
|
||||
typedef struct D3D11_VIDEO_DECODER_DESC
|
||||
{
|
||||
GUID Guid;
|
||||
|
||||
@@ -4523,7 +4523,7 @@ EXTERN_C const IID IID_ID3D12GraphicsCommandList;
|
||||
|
||||
virtual void STDMETHODCALLTYPE SetDescriptorHeaps(
|
||||
_In_ UINT NumDescriptorHeaps,
|
||||
_In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap *const *ppDescriptorHeaps) = 0;
|
||||
_In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap **ppDescriptorHeaps) = 0;
|
||||
|
||||
virtual void STDMETHODCALLTYPE SetComputeRootSignature(
|
||||
_In_ ID3D12RootSignature *pRootSignature) = 0;
|
||||
@@ -4600,7 +4600,7 @@ EXTERN_C const IID IID_ID3D12GraphicsCommandList;
|
||||
|
||||
virtual void STDMETHODCALLTYPE OMSetRenderTargets(
|
||||
_In_ UINT NumRenderTargetDescriptors,
|
||||
_In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors,
|
||||
_In_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors,
|
||||
_In_ BOOL RTsSingleHandleToDescriptorRange,
|
||||
_In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pDepthStencilDescriptor) = 0;
|
||||
|
||||
@@ -4840,7 +4840,7 @@ EXTERN_C const IID IID_ID3D12GraphicsCommandList;
|
||||
void ( STDMETHODCALLTYPE *SetDescriptorHeaps )(
|
||||
ID3D12GraphicsCommandList * This,
|
||||
_In_ UINT NumDescriptorHeaps,
|
||||
_In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap *const *ppDescriptorHeaps);
|
||||
_In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap **ppDescriptorHeaps);
|
||||
|
||||
void ( STDMETHODCALLTYPE *SetComputeRootSignature )(
|
||||
ID3D12GraphicsCommandList * This,
|
||||
@@ -4935,7 +4935,7 @@ EXTERN_C const IID IID_ID3D12GraphicsCommandList;
|
||||
void ( STDMETHODCALLTYPE *OMSetRenderTargets )(
|
||||
ID3D12GraphicsCommandList * This,
|
||||
_In_ UINT NumRenderTargetDescriptors,
|
||||
_In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors,
|
||||
_In_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors,
|
||||
_In_ BOOL RTsSingleHandleToDescriptorRange,
|
||||
_In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pDepthStencilDescriptor);
|
||||
|
||||
|
||||
@@ -1459,27 +1459,7 @@ enum D3D12_MESSAGE_ID
|
||||
D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE = ( D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE + 1 ) ,
|
||||
D3D12_MESSAGE_ID_NO_GRAPHICS_API_SUPPORT = ( D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE + 1 ) ,
|
||||
D3D12_MESSAGE_ID_NO_COMPUTE_API_SUPPORT = ( D3D12_MESSAGE_ID_NO_GRAPHICS_API_SUPPORT + 1 ) ,
|
||||
D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_RESOURCE_FLAGS_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_NO_COMPUTE_API_SUPPORT + 1 ) ,
|
||||
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_ROOT_ARGUMENT_UNINITIALIZED = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_RESOURCE_FLAGS_NOT_SUPPORTED + 1 ) ,
|
||||
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_HEAP_INDEX_OUT_OF_BOUNDS = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_ROOT_ARGUMENT_UNINITIALIZED + 1 ) ,
|
||||
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_TABLE_REGISTER_INDEX_OUT_OF_BOUNDS = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_HEAP_INDEX_OUT_OF_BOUNDS + 1 ) ,
|
||||
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_UNINITIALIZED = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_TABLE_REGISTER_INDEX_OUT_OF_BOUNDS + 1 ) ,
|
||||
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_UNINITIALIZED + 1 ) ,
|
||||
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_SRV_RESOURCE_DIMENSION_MISMATCH = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_TYPE_MISMATCH + 1 ) ,
|
||||
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_UAV_RESOURCE_DIMENSION_MISMATCH = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_SRV_RESOURCE_DIMENSION_MISMATCH + 1 ) ,
|
||||
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_UAV_RESOURCE_DIMENSION_MISMATCH + 1 ) ,
|
||||
D3D12_MESSAGE_ID_COPYRESOURCE_NULLDST = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE + 1 ) ,
|
||||
D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDDSTRESOURCE = ( D3D12_MESSAGE_ID_COPYRESOURCE_NULLDST + 1 ) ,
|
||||
D3D12_MESSAGE_ID_COPYRESOURCE_NULLSRC = ( D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDDSTRESOURCE + 1 ) ,
|
||||
D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDSRCRESOURCE = ( D3D12_MESSAGE_ID_COPYRESOURCE_NULLSRC + 1 ) ,
|
||||
D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLDST = ( D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDSRCRESOURCE + 1 ) ,
|
||||
D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDDSTRESOURCE = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLDST + 1 ) ,
|
||||
D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLSRC = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDDSTRESOURCE + 1 ) ,
|
||||
D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDSRCRESOURCE = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLSRC + 1 ) ,
|
||||
D3D12_MESSAGE_ID_PIPELINE_STATE_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDSRCRESOURCE + 1 ) ,
|
||||
D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_NOT_SET = ( D3D12_MESSAGE_ID_PIPELINE_STATE_TYPE_MISMATCH + 1 ) ,
|
||||
D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_MISMATCH = ( D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_NOT_SET + 1 ) ,
|
||||
D3D12_MESSAGE_ID_D3D12_MESSAGES_END = ( D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_MISMATCH + 1 )
|
||||
D3D12_MESSAGE_ID_D3D12_MESSAGES_END = ( D3D12_MESSAGE_ID_NO_COMPUTE_API_SUPPORT + 1 )
|
||||
} D3D12_MESSAGE_ID;
|
||||
|
||||
typedef struct D3D12_MESSAGE
|
||||
|
||||
@@ -2446,7 +2446,7 @@ enum DWRITE_NUMBER_SUBSTITUTION_METHOD
|
||||
/// <summary>
|
||||
/// Holds the appropriate digits and numeric punctuation for a given locale.
|
||||
/// </summary>
|
||||
interface DWRITE_DECLARE_INTERFACE("14885CC9-BAB0-4f90-B6ED-5C366A2CD03D") IDWriteNumberSubstitution : public IUnknown
|
||||
interface DECLSPEC_UUID("14885CC9-BAB0-4f90-B6ED-5C366A2CD03D") DECLSPEC_NOVTABLE IDWriteNumberSubstitution : public IUnknown
|
||||
{
|
||||
};
|
||||
|
||||
@@ -2511,7 +2511,7 @@ struct DWRITE_SHAPING_GLYPH_PROPERTIES
|
||||
/// stop prematurely and return a callback error. Rather than return E_NOTIMPL,
|
||||
/// an application should stub the method and return a constant/null and S_OK.
|
||||
/// </summary>
|
||||
interface DWRITE_DECLARE_INTERFACE("688e1a58-5094-47c8-adc8-fbcea60ae92b") IDWriteTextAnalysisSource : public IUnknown
|
||||
interface DECLSPEC_UUID("688e1a58-5094-47c8-adc8-fbcea60ae92b") DECLSPEC_NOVTABLE IDWriteTextAnalysisSource : public IUnknown
|
||||
{
|
||||
/// <summary>
|
||||
/// Get a block of text starting at the specified text position.
|
||||
@@ -2620,7 +2620,7 @@ interface DWRITE_DECLARE_INTERFACE("688e1a58-5094-47c8-adc8-fbcea60ae92b") IDWri
|
||||
/// state of the analysis sink, therefore a Set method call on a range
|
||||
/// overwrites the previously set analysis result of the same range.
|
||||
/// </summary>
|
||||
interface DWRITE_DECLARE_INTERFACE("5810cd44-0ca0-4701-b3fa-bec5182ae4f6") IDWriteTextAnalysisSink : public IUnknown
|
||||
interface DECLSPEC_UUID("5810cd44-0ca0-4701-b3fa-bec5182ae4f6") DECLSPEC_NOVTABLE IDWriteTextAnalysisSink : public IUnknown
|
||||
{
|
||||
/// <summary>
|
||||
/// Report script analysis for the text range.
|
||||
|
||||
@@ -1714,7 +1714,7 @@ interface DWRITE_DECLARE_INTERFACE("80DAD800-E21F-4E83-96CE-BFCCE500DB7C") IDWri
|
||||
/// If any of these callbacks returns an error, the analysis functions will
|
||||
/// stop prematurely and return a callback error.
|
||||
/// </summary>
|
||||
interface DWRITE_DECLARE_INTERFACE("639CFAD8-0FB4-4B21-A58A-067920120009") IDWriteTextAnalysisSource1 : public IDWriteTextAnalysisSource
|
||||
interface DECLSPEC_UUID("{639CFAD8-0FB4-4B21-A58A-067920120009}") DECLSPEC_NOVTABLE IDWriteTextAnalysisSource1 : public IDWriteTextAnalysisSource
|
||||
{
|
||||
/// <summary>
|
||||
/// The text analyzer calls back to this to get the desired glyph
|
||||
@@ -1753,7 +1753,7 @@ interface DWRITE_DECLARE_INTERFACE("639CFAD8-0FB4-4B21-A58A-067920120009") IDWri
|
||||
/// The interface implemented by the client to receive the
|
||||
/// output of the text analyzers.
|
||||
/// </summary>
|
||||
interface DWRITE_DECLARE_INTERFACE("B0D941A0-85E7-4D8B-9FD3-5CED9934482A") IDWriteTextAnalysisSink1 : public IDWriteTextAnalysisSink
|
||||
interface DECLSPEC_UUID("B0D941A0-85E7-4D8B-9FD3-5CED9934482A") DECLSPEC_NOVTABLE IDWriteTextAnalysisSink1 : public IDWriteTextAnalysisSink
|
||||
{
|
||||
/// <summary>
|
||||
/// The text analyzer calls back to this to report the actual orientation
|
||||
|
||||
@@ -1,294 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Module Name:
|
||||
|
||||
sdkddkver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Master include file for versioning windows SDK/DDK.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _INC_SDKDDKVER
|
||||
#define _INC_SDKDDKVER
|
||||
|
||||
#if (_MSC_VER >= 800)
|
||||
#if (_MSC_VER >= 1200)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4668) /* #if not_defined treated as #if 0 */
|
||||
#endif
|
||||
#pragma warning(disable:4001) /* nonstandard extension : single line comment */
|
||||
#endif
|
||||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// _WIN32_WINNT version constants
|
||||
//
|
||||
#define _WIN32_WINNT_NT4 0x0400
|
||||
#define _WIN32_WINNT_WIN2K 0x0500
|
||||
#define _WIN32_WINNT_WINXP 0x0501
|
||||
#define _WIN32_WINNT_WS03 0x0502
|
||||
#define _WIN32_WINNT_WIN6 0x0600
|
||||
#define _WIN32_WINNT_VISTA 0x0600
|
||||
#define _WIN32_WINNT_WS08 0x0600
|
||||
#define _WIN32_WINNT_LONGHORN 0x0600
|
||||
#define _WIN32_WINNT_WIN7 0x0601
|
||||
#define _WIN32_WINNT_WIN8 0x0602
|
||||
#define _WIN32_WINNT_WINBLUE 0x0603
|
||||
#define _WIN32_WINNT_WINTHRESHOLD 0x0A00 /* ABRACADABRA_THRESHOLD*/
|
||||
#define _WIN32_WINNT_WIN10 0x0A00 /* ABRACADABRA_THRESHOLD*/
|
||||
|
||||
//
|
||||
// _WIN32_IE_ version constants
|
||||
//
|
||||
#define _WIN32_IE_IE20 0x0200
|
||||
#define _WIN32_IE_IE30 0x0300
|
||||
#define _WIN32_IE_IE302 0x0302
|
||||
#define _WIN32_IE_IE40 0x0400
|
||||
#define _WIN32_IE_IE401 0x0401
|
||||
#define _WIN32_IE_IE50 0x0500
|
||||
#define _WIN32_IE_IE501 0x0501
|
||||
#define _WIN32_IE_IE55 0x0550
|
||||
#define _WIN32_IE_IE60 0x0600
|
||||
#define _WIN32_IE_IE60SP1 0x0601
|
||||
#define _WIN32_IE_IE60SP2 0x0603
|
||||
#define _WIN32_IE_IE70 0x0700
|
||||
#define _WIN32_IE_IE80 0x0800
|
||||
#define _WIN32_IE_IE90 0x0900
|
||||
#define _WIN32_IE_IE100 0x0A00
|
||||
#define _WIN32_IE_IE110 0x0A00 /* ABRACADABRA_THRESHOLD */
|
||||
|
||||
//
|
||||
// IE <-> OS version mapping
|
||||
//
|
||||
// NT4 supports IE versions 2.0 -> 6.0 SP1
|
||||
#define _WIN32_IE_NT4 _WIN32_IE_IE20
|
||||
#define _WIN32_IE_NT4SP1 _WIN32_IE_IE20
|
||||
#define _WIN32_IE_NT4SP2 _WIN32_IE_IE20
|
||||
#define _WIN32_IE_NT4SP3 _WIN32_IE_IE302
|
||||
#define _WIN32_IE_NT4SP4 _WIN32_IE_IE401
|
||||
#define _WIN32_IE_NT4SP5 _WIN32_IE_IE401
|
||||
#define _WIN32_IE_NT4SP6 _WIN32_IE_IE50
|
||||
// Win98 supports IE versions 4.01 -> 6.0 SP1
|
||||
#define _WIN32_IE_WIN98 _WIN32_IE_IE401
|
||||
// Win98SE supports IE versions 5.0 -> 6.0 SP1
|
||||
#define _WIN32_IE_WIN98SE _WIN32_IE_IE50
|
||||
// WinME supports IE versions 5.5 -> 6.0 SP1
|
||||
#define _WIN32_IE_WINME _WIN32_IE_IE55
|
||||
// Win2k supports IE versions 5.01 -> 6.0 SP1
|
||||
#define _WIN32_IE_WIN2K _WIN32_IE_IE501
|
||||
#define _WIN32_IE_WIN2KSP1 _WIN32_IE_IE501
|
||||
#define _WIN32_IE_WIN2KSP2 _WIN32_IE_IE501
|
||||
#define _WIN32_IE_WIN2KSP3 _WIN32_IE_IE501
|
||||
#define _WIN32_IE_WIN2KSP4 _WIN32_IE_IE501
|
||||
#define _WIN32_IE_XP _WIN32_IE_IE60
|
||||
#define _WIN32_IE_XPSP1 _WIN32_IE_IE60SP1
|
||||
#define _WIN32_IE_XPSP2 _WIN32_IE_IE60SP2
|
||||
#define _WIN32_IE_WS03 0x0602
|
||||
#define _WIN32_IE_WS03SP1 _WIN32_IE_IE60SP2
|
||||
#define _WIN32_IE_WIN6 _WIN32_IE_IE70
|
||||
#define _WIN32_IE_LONGHORN _WIN32_IE_IE70
|
||||
#define _WIN32_IE_WIN7 _WIN32_IE_IE80
|
||||
#define _WIN32_IE_WIN8 _WIN32_IE_IE100
|
||||
#define _WIN32_IE_WINBLUE _WIN32_IE_IE100
|
||||
#define _WIN32_IE_WINTHRESHOLD _WIN32_IE_IE110 /* ABRACADABRA_THRESHOLD */
|
||||
#define _WIN32_IE_WIN10 _WIN32_IE_IE110 /* ABRACADABRA_THRESHOLD */
|
||||
|
||||
|
||||
//
|
||||
// NTDDI version constants
|
||||
//
|
||||
#define NTDDI_WIN2K 0x05000000
|
||||
#define NTDDI_WIN2KSP1 0x05000100
|
||||
#define NTDDI_WIN2KSP2 0x05000200
|
||||
#define NTDDI_WIN2KSP3 0x05000300
|
||||
#define NTDDI_WIN2KSP4 0x05000400
|
||||
|
||||
#define NTDDI_WINXP 0x05010000
|
||||
#define NTDDI_WINXPSP1 0x05010100
|
||||
#define NTDDI_WINXPSP2 0x05010200
|
||||
#define NTDDI_WINXPSP3 0x05010300
|
||||
#define NTDDI_WINXPSP4 0x05010400
|
||||
|
||||
#define NTDDI_WS03 0x05020000
|
||||
#define NTDDI_WS03SP1 0x05020100
|
||||
#define NTDDI_WS03SP2 0x05020200
|
||||
#define NTDDI_WS03SP3 0x05020300
|
||||
#define NTDDI_WS03SP4 0x05020400
|
||||
|
||||
#define NTDDI_WIN6 0x06000000
|
||||
#define NTDDI_WIN6SP1 0x06000100
|
||||
#define NTDDI_WIN6SP2 0x06000200
|
||||
#define NTDDI_WIN6SP3 0x06000300
|
||||
#define NTDDI_WIN6SP4 0x06000400
|
||||
|
||||
#define NTDDI_VISTA NTDDI_WIN6
|
||||
#define NTDDI_VISTASP1 NTDDI_WIN6SP1
|
||||
#define NTDDI_VISTASP2 NTDDI_WIN6SP2
|
||||
#define NTDDI_VISTASP3 NTDDI_WIN6SP3
|
||||
#define NTDDI_VISTASP4 NTDDI_WIN6SP4
|
||||
|
||||
#define NTDDI_LONGHORN NTDDI_VISTA
|
||||
|
||||
#define NTDDI_WS08 NTDDI_WIN6SP1
|
||||
#define NTDDI_WS08SP2 NTDDI_WIN6SP2
|
||||
#define NTDDI_WS08SP3 NTDDI_WIN6SP3
|
||||
#define NTDDI_WS08SP4 NTDDI_WIN6SP4
|
||||
|
||||
#define NTDDI_WIN7 0x06010000
|
||||
#define NTDDI_WIN8 0x06020000
|
||||
#define NTDDI_WINBLUE 0x06030000
|
||||
#define NTDDI_WINTHRESHOLD 0x0A000000 /* ABRACADABRA_THRESHOLD */
|
||||
#define NTDDI_WIN10 0x0A000000 /* ABRACADABRA_THRESHOLD */
|
||||
#define NTDDI_WIN10_TH2 0x0A000001 /* ABRACADABRA_WIN10_TH2 */
|
||||
|
||||
//
|
||||
// masks for version macros
|
||||
//
|
||||
#define OSVERSION_MASK 0xFFFF0000
|
||||
#define SPVERSION_MASK 0x0000FF00
|
||||
#define SUBVERSION_MASK 0x000000FF
|
||||
|
||||
|
||||
//
|
||||
// macros to extract various version fields from the NTDDI version
|
||||
//
|
||||
#define OSVER(Version) ((Version) & OSVERSION_MASK)
|
||||
#define SPVER(Version) (((Version) & SPVERSION_MASK) >> 8)
|
||||
#define SUBVER(Version) (((Version) & SUBVERSION_MASK) )
|
||||
|
||||
|
||||
#if defined(DECLSPEC_DEPRECATED_DDK)
|
||||
|
||||
// deprecate in 2k or later
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN2K)
|
||||
#define DECLSPEC_DEPRECATED_DDK_WIN2K DECLSPEC_DEPRECATED_DDK
|
||||
#else
|
||||
#define DECLSPEC_DEPRECATED_DDK_WIN2K
|
||||
#endif
|
||||
|
||||
// deprecate in XP or later
|
||||
#if (NTDDI_VERSION >= NTDDI_WINXP)
|
||||
#define DECLSPEC_DEPRECATED_DDK_WINXP DECLSPEC_DEPRECATED_DDK
|
||||
#else
|
||||
#define DECLSPEC_DEPRECATED_DDK_WINXP
|
||||
#endif
|
||||
|
||||
// deprecate in WS03 or later
|
||||
#if (NTDDI_VERSION >= NTDDI_WS03)
|
||||
#define DECLSPEC_DEPRECATED_DDK_WIN2003 DECLSPEC_DEPRECATED_DDK
|
||||
#else
|
||||
#define DECLSPEC_DEPRECATED_DDK_WIN2003
|
||||
#endif
|
||||
|
||||
// deprecate in WIN6 or later
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN6)
|
||||
#define DECLSPEC_DEPRECATED_DDK_WIN6 DECLSPEC_DEPRECATED_DDK
|
||||
#else
|
||||
#define DECLSPEC_DEPRECATED_DDK_WIN6
|
||||
#endif
|
||||
|
||||
#define DECLSPEC_DEPRECATED_DDK_LONGHORN DECLSPEC_DEPRECATED_DDK_WIN6
|
||||
|
||||
#endif // defined(DECLSPEC_DEPRECATED_DDK)
|
||||
|
||||
|
||||
//
|
||||
// if versions aren't already defined, default to most current
|
||||
//
|
||||
|
||||
#define NTDDI_VERSION_FROM_WIN32_WINNT2(ver) ver##0000
|
||||
#define NTDDI_VERSION_FROM_WIN32_WINNT(ver) NTDDI_VERSION_FROM_WIN32_WINNT2(ver)
|
||||
|
||||
#if !defined(_WIN32_WINNT) && !defined(_CHICAGO_)
|
||||
#define _WIN32_WINNT 0x0A00
|
||||
#endif
|
||||
|
||||
#ifndef NTDDI_VERSION
|
||||
#ifdef _WIN32_WINNT
|
||||
// set NTDDI_VERSION based on _WIN32_WINNT
|
||||
#define NTDDI_VERSION NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT)
|
||||
#else
|
||||
#define NTDDI_VERSION 0x0A000001
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WINVER
|
||||
#ifdef _WIN32_WINNT
|
||||
// set WINVER based on _WIN32_WINNT
|
||||
#define WINVER _WIN32_WINNT
|
||||
#else
|
||||
#define WINVER 0x0A00
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_IE
|
||||
#ifdef _WIN32_WINNT
|
||||
// set _WIN32_IE based on _WIN32_WINNT
|
||||
#if (_WIN32_WINNT <= _WIN32_WINNT_NT4)
|
||||
#define _WIN32_IE _WIN32_IE_IE50
|
||||
#elif (_WIN32_WINNT <= _WIN32_WINNT_WIN2K)
|
||||
#define _WIN32_IE _WIN32_IE_IE501
|
||||
#elif (_WIN32_WINNT <= _WIN32_WINNT_WINXP)
|
||||
#define _WIN32_IE _WIN32_IE_IE60
|
||||
#elif (_WIN32_WINNT <= _WIN32_WINNT_WS03)
|
||||
#define _WIN32_IE _WIN32_IE_WS03
|
||||
#elif (_WIN32_WINNT <= _WIN32_WINNT_VISTA)
|
||||
#define _WIN32_IE _WIN32_IE_LONGHORN
|
||||
#elif (_WIN32_WINNT <= _WIN32_WINNT_WIN7)
|
||||
#define _WIN32_IE _WIN32_IE_WIN7
|
||||
#elif (_WIN32_WINNT <= _WIN32_WINNT_WIN8)
|
||||
#define _WIN32_IE _WIN32_IE_WIN8
|
||||
#else
|
||||
#define _WIN32_IE 0x0A00
|
||||
#endif
|
||||
#else
|
||||
#define _WIN32_IE 0x0A00
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Sanity check for compatible versions
|
||||
//
|
||||
#if defined(_WIN32_WINNT) && !defined(MIDL_PASS) && !defined(RC_INVOKED)
|
||||
|
||||
#if (defined(WINVER) && (WINVER < 0x0400) && (_WIN32_WINNT > 0x0400))
|
||||
#error WINVER setting conflicts with _WIN32_WINNT setting
|
||||
#endif
|
||||
|
||||
#if (((OSVERSION_MASK & NTDDI_VERSION) == NTDDI_WIN2K) && (_WIN32_WINNT != _WIN32_WINNT_WIN2K))
|
||||
#error NTDDI_VERSION setting conflicts with _WIN32_WINNT setting
|
||||
#endif
|
||||
|
||||
#if (((OSVERSION_MASK & NTDDI_VERSION) == NTDDI_WINXP) && (_WIN32_WINNT != _WIN32_WINNT_WINXP))
|
||||
#error NTDDI_VERSION setting conflicts with _WIN32_WINNT setting
|
||||
#endif
|
||||
|
||||
#if (((OSVERSION_MASK & NTDDI_VERSION) == NTDDI_WS03) && (_WIN32_WINNT != _WIN32_WINNT_WS03))
|
||||
#error NTDDI_VERSION setting conflicts with _WIN32_WINNT setting
|
||||
#endif
|
||||
|
||||
#if (((OSVERSION_MASK & NTDDI_VERSION) == NTDDI_VISTA) && (_WIN32_WINNT != _WIN32_WINNT_VISTA))
|
||||
#error NTDDI_VERSION setting conflicts with _WIN32_WINNT setting
|
||||
#endif
|
||||
|
||||
#if ((_WIN32_WINNT < _WIN32_WINNT_WIN2K) && (_WIN32_IE > _WIN32_IE_IE60SP1))
|
||||
#error _WIN32_WINNT settings conflicts with _WIN32_IE setting
|
||||
#endif
|
||||
|
||||
#endif // defined(_WIN32_WINNT) && !defined(MIDL_PASS) && !defined(_WINRESRC_)
|
||||
|
||||
#if (_MSC_VER >= 800)
|
||||
#if (_MSC_VER >= 1200)
|
||||
#pragma warning(pop)
|
||||
#else
|
||||
#pragma warning(default:4001) /* nonstandard extension : single line comment */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* !_INC_SDKDDKVER */
|
||||
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Module Name:
|
||||
|
||||
winapifamily.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Master include file for API family partitioning.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _INC_WINAPIFAMILY
|
||||
#define _INC_WINAPIFAMILY
|
||||
|
||||
#if defined(_MSC_VER) && !defined(MOFCOMP_PASS)
|
||||
#if _MSC_VER >= 1200
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4001) /* nonstandard extension 'single line comment' was used */
|
||||
#endif
|
||||
#pragma once
|
||||
#endif // defined(_MSC_VER) && !defined(MOFCOMP_PASS)
|
||||
|
||||
#include <winpackagefamily.h>
|
||||
|
||||
/*
|
||||
* When compiling C and C++ code using SDK header files, the development
|
||||
* environment can specify a target platform by #define-ing the
|
||||
* pre-processor symbol WINAPI_FAMILY to one of the following values.
|
||||
* Each FAMILY value denotes an application family for which a different
|
||||
* subset of the total set of header-file-defined APIs are available.
|
||||
* Setting the WINAPI_FAMILY value will effectively hide from the
|
||||
* editing and compilation environments the existence of APIs that
|
||||
* are not applicable to the family of applications targeting a
|
||||
* specific platform.
|
||||
*/
|
||||
|
||||
/* In Windows 10, WINAPI_PARTITIONs will be used to add additional
|
||||
* device specific APIs to a particular WINAPI_FAMILY.
|
||||
* For example, when writing Windows Universal apps, specifying
|
||||
* WINAPI_FAMILY_APP will hide phone APIs from compilation.
|
||||
* However, specifying WINAPI_PARTITION_PHONE_APP=1 additionally, will
|
||||
* unhide any API hidden behind the partition, to the compiler.
|
||||
|
||||
* The following partitions are currently defined:
|
||||
* WINAPI_PARTITION_DESKTOP // usable for Desktop Win32 apps (but not store apps)
|
||||
* WINAPI_PARTITION_APP // usable for Windows Universal store apps
|
||||
* WINAPI_PARTITION_PC_APP // specific to Desktop-only store apps
|
||||
* WINAPI_PARTITION_PHONE_APP // specific to Phone-only store apps
|
||||
* WINAPI_PARTITION_SYSTEM // specific to System applications
|
||||
|
||||
* The following partitions are indirect partitions and defined in
|
||||
* winpackagefamily.h. These partitions are related to package based
|
||||
* partitions. For example, specifying WINAPI_PARTITION_SERVER=1 will light up
|
||||
* any API hidden behind the package based partitions that are bound to
|
||||
* WINAPI_PARTITION_SERVER, to the compiler.
|
||||
* WINAPI_PARTITION_SERVER // specific to Server applications
|
||||
*/
|
||||
|
||||
/*
|
||||
* The WINAPI_FAMILY values of 0 and 1 are reserved to ensure that
|
||||
* an error will occur if WINAPI_FAMILY is set to any
|
||||
* WINAPI_PARTITION value (which must be 0 or 1, see below).
|
||||
*/
|
||||
#define WINAPI_FAMILY_PC_APP 2 /* Windows Store Applications */
|
||||
#define WINAPI_FAMILY_PHONE_APP 3 /* Windows Phone Applications */
|
||||
#define WINAPI_FAMILY_SYSTEM 4 /* Windows Drivers and Tools */
|
||||
#define WINAPI_FAMILY_SERVER 5 /* Windows Server Applications */
|
||||
#define WINAPI_FAMILY_DESKTOP_APP 100 /* Windows Desktop Applications */
|
||||
/* The value of WINAPI_FAMILY_DESKTOP_APP may change in future SDKs. */
|
||||
/* Additional WINAPI_FAMILY values may be defined in future SDKs. */
|
||||
|
||||
/*
|
||||
* For compatibility with Windows 8 header files, the following
|
||||
* synonym for WINAPI_FAMILY_PC_APP is temporarily #define'd.
|
||||
* Use of this symbol should be considered deprecated.
|
||||
*/
|
||||
#define WINAPI_FAMILY_APP WINAPI_FAMILY_PC_APP
|
||||
|
||||
/*
|
||||
* If no WINAPI_FAMILY value is specified, then all APIs available to
|
||||
* Windows desktop applications are exposed.
|
||||
*/
|
||||
#ifndef WINAPI_FAMILY
|
||||
#define WINAPI_FAMILY WINAPI_FAMILY_DESKTOP_APP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* API PARTITONs are part of an indirection mechanism for mapping between
|
||||
* individual APIs and the FAMILYs to which they apply.
|
||||
* Each PARTITION is a category or subset of named APIs. PARTITIONs
|
||||
* are permitted to have overlapping membership -- some single API
|
||||
* might be part of more than one PARTITION. PARTITIONS are each #define-ed
|
||||
* to be either 1 or 0 or depending on the platform at which the app is targeted.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The mapping between families and partitions is summarized here.
|
||||
* An X indicates that the given partition is active for the given
|
||||
* platform/family.
|
||||
*
|
||||
* +-------------------+---+
|
||||
* | *Partition* | |
|
||||
* +---+---+---+---+---+---+
|
||||
* | | | | | | |
|
||||
* | | | | | | |
|
||||
* | | | | P | | |
|
||||
* | | | | H | | |
|
||||
* | D | | | O | | |
|
||||
* | E | | P | N | S | S |
|
||||
* | S | | C | E | Y | E |
|
||||
* | K | | _ | _ | S | R |
|
||||
* | T | A | A | A | T | V |
|
||||
* +-------------------------+----+ O | P | P | P | E | E |
|
||||
* | *Platform/Family* \| P | P | P | P | M | R |
|
||||
* +------------------------------+---+---+---+---+---+---+
|
||||
* | WINAPI_FAMILY_DESKTOP_APP | X | X | X | | | |
|
||||
* +------------------------------+---+---+---+---+---+---+
|
||||
* | WINAPI_FAMILY_PC_APP | | X | X | | | |
|
||||
* +------------------------------+---+---+---+---+---+---+
|
||||
* | WINAPI_FAMILY_PHONE_APP | | X | | X | | |
|
||||
* +----------------------------- +---+---+---+---+---+---+
|
||||
* | WINAPI_FAMILY_SYSTEM | | | | | X | |
|
||||
* +----------------------------- +---+---+---+---+---+---+
|
||||
* | WINAPI_FAMILY_SERVER | | | | | X | X |
|
||||
* +------------------------------+---+---+---+---+---+---+
|
||||
*
|
||||
* The table above is encoded in the following expressions,
|
||||
* each of which evaluates to 1 or 0.
|
||||
*
|
||||
* Whenever a new family is added, all of these expressions
|
||||
* need to be reconsidered.
|
||||
*/
|
||||
#if WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP && \
|
||||
WINAPI_FAMILY != WINAPI_FAMILY_PC_APP && \
|
||||
WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP && \
|
||||
WINAPI_FAMILY != WINAPI_FAMILY_SYSTEM && \
|
||||
WINAPI_FAMILY != WINAPI_FAMILY_SERVER
|
||||
#error Unknown WINAPI_FAMILY value. Was it defined in terms of a WINAPI_PARTITION_* value?
|
||||
#endif
|
||||
|
||||
#ifndef WINAPI_PARTITION_DESKTOP
|
||||
#define WINAPI_PARTITION_DESKTOP (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
|
||||
#endif
|
||||
|
||||
#ifndef WINAPI_PARTITION_APP
|
||||
#define WINAPI_PARTITION_APP \
|
||||
(WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP || \
|
||||
WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || \
|
||||
WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
#endif
|
||||
|
||||
#ifndef WINAPI_PARTITION_PC_APP
|
||||
#define WINAPI_PARTITION_PC_APP \
|
||||
(WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP || \
|
||||
WINAPI_FAMILY == WINAPI_FAMILY_PC_APP)
|
||||
#endif
|
||||
|
||||
#ifndef WINAPI_PARTITION_PHONE_APP
|
||||
#define WINAPI_PARTITION_PHONE_APP (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SYSTEM is the only partition defined here.
|
||||
* All other System based editions are defined as packages
|
||||
* on top of the System partition.
|
||||
* See winpackagefamily.h for packages level partitions
|
||||
*/
|
||||
#ifndef WINAPI_PARTITION_SYSTEM
|
||||
#define WINAPI_PARTITION_SYSTEM \
|
||||
(WINAPI_FAMILY == WINAPI_FAMILY_SYSTEM || \
|
||||
WINAPI_FAMILY == WINAPI_FAMILY_SERVER)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For compatibility with Windows Phone 8 header files, the following
|
||||
* synonym for WINAPI_PARTITION_PHONE_APP is temporarily #define'd.
|
||||
* Use of this symbol should be regarded as deprecated.
|
||||
*/
|
||||
#define WINAPI_PARTITION_PHONE WINAPI_PARTITION_PHONE_APP
|
||||
|
||||
/*
|
||||
* Header files use the WINAPI_FAMILY_PARTITION macro to assign one or
|
||||
* more declarations to some group of partitions. The macro chooses
|
||||
* whether the preprocessor will emit or omit a sequence of declarations
|
||||
* bracketed by an #if/#endif pair. All header file references to the
|
||||
* WINAPI_PARTITION_* values should be in the form of occurrences of
|
||||
* WINAPI_FAMILY_PARTITION(...).
|
||||
*
|
||||
* For example, the following usage of WINAPI_FAMILY_PARTITION identifies
|
||||
* a sequence of declarations that are part of both the Windows Desktop
|
||||
* Partition and the Windows-Phone-Specific Store Partition:
|
||||
*
|
||||
* #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PHONE_APP)
|
||||
* ...
|
||||
* #endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PHONE_APP)
|
||||
*
|
||||
* The comment on the closing #endif allow tools as well as people to find the
|
||||
* matching #ifdef properly.
|
||||
*
|
||||
* Usages of WINAPI_FAMILY_PARTITION may be combined, when the partitition definitions are
|
||||
* related. In particular one might use declarations like
|
||||
*
|
||||
* #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
*
|
||||
* or
|
||||
*
|
||||
* #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
|
||||
*
|
||||
* Direct references to WINAPI_PARTITION_ values (eg #if !WINAPI_FAMILY_PARTITION_...)
|
||||
* should not be used.
|
||||
*/
|
||||
#define WINAPI_FAMILY_PARTITION(Partitions) (Partitions)
|
||||
|
||||
/*
|
||||
* Macro used to #define or typedef a symbol used for selective deprecation
|
||||
* of individual methods of a COM interfaces that are otherwise available
|
||||
* for a given set of partitions.
|
||||
*/
|
||||
#define _WINAPI_DEPRECATED_DECLARATION __declspec(deprecated("This API cannot be used in the context of the caller's application type."))
|
||||
|
||||
/*
|
||||
* For compatibility with Windows 8 header files, the following
|
||||
* symbol is temporarily conditionally #define'd. Additional symbols
|
||||
* like this should be not defined in winapifamily.h, but rather should be
|
||||
* introduced locally to the header files of the component that needs them.
|
||||
*/
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
# define APP_DEPRECATED_HRESULT HRESULT _WINAPI_DEPRECATED_DECLARATION
|
||||
#endif // WINAPIFAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
|
||||
#if defined(_MSC_VER) && !defined(MOFCOMP_PASS)
|
||||
#if _MSC_VER >= 1200
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* !_INC_WINAPIFAMILY */
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Module Name:
|
||||
|
||||
winpackagefamily.h
|
||||
|
||||
Abstract:
|
||||
|
||||
API family partitioning based on packages.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _INC_WINPACKAGEFAMILY
|
||||
#define _INC_WINPACKAGEFAMILY
|
||||
|
||||
#if defined(_MSC_VER) && !defined(MOFCOMP_PASS)
|
||||
#if _MSC_VER >= 1200
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4001) /* nonstandard extension 'single line comment' was used */
|
||||
#endif
|
||||
#pragma once
|
||||
#endif // defined(_MSC_VER) && !defined(MOFCOMP_PASS)
|
||||
|
||||
#ifndef WINAPI_PARTITION_SERVER
|
||||
#define WINAPI_PARTITION_SERVER (WINAPI_FAMILY == WINAPI_FAMILY_SERVER)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PARTITIONS based on packages are each #undef'ed below, and then will be #define-ed
|
||||
* to be either 1 or 0 or depending on the active WINAPI_FAMILY.
|
||||
*/
|
||||
#undef WINAPI_PARTITION_PKG_WINTRUST
|
||||
#undef WINAPI_PARTITION_PKG_WEBSERVICES
|
||||
#undef WINAPI_PARTITION_PKG_EVENTLOGSERVICE
|
||||
#undef WINAPI_PARTITION_PKG_VHD
|
||||
#undef WINAPI_PARTITION_PKG_PERFCOUNTER
|
||||
#undef WINAPI_PARTITION_PKG_SECURESTARTUP
|
||||
#undef WINAPI_PARTITION_PKG_REMOTEFS
|
||||
#undef WINAPI_PARTITION_PKG_BOOTABLESKU
|
||||
#undef WINAPI_PARTITION_PKG_CMD
|
||||
#undef WINAPI_PARTITION_PKG_CMDTOOLS
|
||||
#undef WINAPI_PARTITION_PKG_DISM
|
||||
#undef WINAPI_PARTITION_PKG_CORESETUP
|
||||
#undef WINAPI_PARTITION_PKG_APPRUNTIME
|
||||
#undef WINAPI_PARTITION_PKG_ESENT
|
||||
#undef WINAPI_PARTITION_PKG_WINMGMT
|
||||
#undef WINAPI_PARTITION_PKG_WNV
|
||||
#undef WINAPI_PARTITION_PKG_CLUSTER
|
||||
#undef WINAPI_PARTITION_PKG_VSS
|
||||
|
||||
/*
|
||||
* PARTITIONS for feature packages. Each package might be active for one or more editions
|
||||
*/
|
||||
#define WINAPI_PARTITION_PKG_WINTRUST (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_WEBSERVICES (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_EVENTLOGSERVICE (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_VHD (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_PERFCOUNTER (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_SECURESTARTUP (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_REMOTEFS (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_BOOTABLESKU (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_CMD (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_CMDTOOLS (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_DISM (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_CORESETUP (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_APPRUNTIME (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_ESENT (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_WINMGMT (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_WNV (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_CLUSTER (WINAPI_PARTITION_SERVER == 1)
|
||||
#define WINAPI_PARTITION_PKG_VSS (WINAPI_PARTITION_SERVER == 1)
|
||||
|
||||
#if defined(_MSC_VER) && !defined(MOFCOMP_PASS)
|
||||
#if _MSC_VER >= 1200
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* !_INC_WINPACKAGEFAMILY */
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -266,7 +266,7 @@ public:
|
||||
.setOptLevel(llvm::CodeGenOpt::Aggressive)
|
||||
.setMCPU("nehalem")
|
||||
.create();
|
||||
module_ptr->setDataLayout(*execution_engine->getDataLayout());
|
||||
module_ptr->setDataLayout(execution_engine->getDataLayout());
|
||||
|
||||
execution_engine->finalizeObject();
|
||||
|
||||
|
||||
@@ -44,50 +44,32 @@
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||
<IncludePath>.\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\minidx12\Include;..\GSL\include</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||
<IncludePath>.\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\minidx12\Include;..\GSL\include</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\rpcs3_default.props" />
|
||||
</ImportGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\;..\rpcs3;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;..\OpenAL\libs\Win64;..\ffmpeg\Windows\x86_64\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\;..\rpcs3;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;..\OpenAL\libs\Win64;..\ffmpeg\Windows\x86_64\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -17,6 +17,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcs3", "rpcs3\rpcs3.vcxpro
|
||||
{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63} = {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}
|
||||
{A1A8355B-0988-528E-9CC2-B971D6266669} = {A1A8355B-0988-528E-9CC2-B971D6266669}
|
||||
{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D} = {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}
|
||||
{8B867186-A0B5-5479-B824-E176EDD27C40} = {8B867186-A0B5-5479-B824-E176EDD27C40}
|
||||
{87B42A9C-3F5C-53D7-9017-2B1CAE39457D} = {87B42A9C-3F5C-53D7-9017-2B1CAE39457D}
|
||||
{8BC303AB-25BE-4276-8E57-73F171B2D672} = {8BC303AB-25BE-4276-8E57-73F171B2D672}
|
||||
@@ -197,6 +198,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XAudio", "rpcs3\XAudio.vcxp
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenAL", "rpcs3\OpenAL.vcxproj", "{30A05C4D-F5FD-421C-A864-17A64BDEAA75}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libpng", "libpng", "{A17D34F1-7E3E-4841-818D-3B7C6F5AF829}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "libpng\projects\vstudio\libpng\libpng.vcxproj", "{D6973076-9317-4EF2-A0B8-B7A18AC0713E}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF} = {60F89955-91C6-3A36-8000-13C592FEC2DF}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "zlib", "zlib", "{F0C19EFA-EDD0-43F2-97C1-18E865E96B4E}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "libpng\projects\vstudio\zlib\zlib.vcxproj", "{60F89955-91C6-3A36-8000-13C592FEC2DF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug - LLVM|x64 = Debug - LLVM|x64
|
||||
@@ -693,6 +705,34 @@ Global
|
||||
{30A05C4D-F5FD-421C-A864-17A64BDEAA75}.Release - LLVM|x64.Build.0 = Release - LLVM|x64
|
||||
{30A05C4D-F5FD-421C-A864-17A64BDEAA75}.Release|x64.ActiveCfg = Release|x64
|
||||
{30A05C4D-F5FD-421C-A864-17A64BDEAA75}.Release|x64.Build.0 = Release|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug - LLVM|x64.ActiveCfg = Debug Library|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug - LLVM|x64.Build.0 = Debug Library|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug - MemLeak|x64.ActiveCfg = Debug Library|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug - MemLeak|x64.Build.0 = Debug Library|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|x64.Build.0 = Debug|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.DLL Debug|x64.ActiveCfg = Debug|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.DLL Debug|x64.Build.0 = Debug|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.DLL Release|x64.ActiveCfg = Release|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.DLL Release|x64.Build.0 = Release|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release - LLVM|x64.ActiveCfg = Release Library|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release - LLVM|x64.Build.0 = Release Library|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|x64.ActiveCfg = Release|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|x64.Build.0 = Release|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug - LLVM|x64.ActiveCfg = Debug Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug - LLVM|x64.Build.0 = Debug Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug - MemLeak|x64.ActiveCfg = Debug Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug - MemLeak|x64.Build.0 = Debug Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug|x64.ActiveCfg = Debug Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Debug|x64.Build.0 = Debug Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.DLL Debug|x64.ActiveCfg = Debug Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.DLL Debug|x64.Build.0 = Debug Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.DLL Release|x64.ActiveCfg = Release Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.DLL Release|x64.Build.0 = Release Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release - LLVM|x64.ActiveCfg = Release Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release - LLVM|x64.Build.0 = Release Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release|x64.ActiveCfg = Release Library|x64
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF}.Release|x64.Build.0 = Release Library|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -730,5 +770,7 @@ Global
|
||||
{7D73447B-3D2D-4DFE-BF62-57E644C1D09F} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
|
||||
{78CB2F39-B809-4A06-8329-8C0A19119D3D} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
|
||||
{30A05C4D-F5FD-421C-A864-17A64BDEAA75} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {A17D34F1-7E3E-4841-818D-3B7C6F5AF829}
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF} = {F0C19EFA-EDD0-43F2-97C1-18E865E96B4E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
+10
-6
@@ -112,6 +112,7 @@ ${LLVM_INCLUDE_DIRS}
|
||||
"${RPCS3_SRC_DIR}/.."
|
||||
"${RPCS3_SRC_DIR}/../asmjit/src/asmjit"
|
||||
"${RPCS3_SRC_DIR}/../glm"
|
||||
"${RPCS3_SRC_DIR}/../libpng"
|
||||
"${RPCS3_SRC_DIR}/../GSL/include"
|
||||
"${RPCS3_SRC_DIR}/../rsx_program_decompiler/rsx_decompiler"
|
||||
"${RPCS3_SRC_DIR}/../rsx_program_decompiler/shader_code"
|
||||
@@ -140,7 +141,10 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
link_directories("${RPCS3_SRC_DIR}/../asmjit/" "${RPCS3_SRC_DIR}/../minidx12/")
|
||||
link_directories(
|
||||
"${RPCS3_SRC_DIR}/../asmjit/"
|
||||
"${RPCS3_SRC_DIR}/../minidx12/"
|
||||
)
|
||||
|
||||
if(MSVC OR NOT WIN32)
|
||||
link_directories("${RPCS3_SRC_DIR}/../ffmpeg/${PLATFORM_ARCH}/lib")
|
||||
@@ -185,14 +189,14 @@ if(WIN32) # I'm not sure we need all of these libs, but we link them in vs
|
||||
else()
|
||||
target_link_libraries(rpcs3 dxgi.lib d2d1.lib dwrite.lib)
|
||||
endif()
|
||||
target_link_libraries(rpcs3 asmjit.lib avformat.lib avcodec.lib avutil.lib swresample.lib swscale.lib ${wxWidgets_LIBRARIES} ${OPENAL_LIBRARY} ${ADDITIONAL_LIBS})
|
||||
target_link_libraries(rpcs3 asmjit.lib avformat.lib avcodec.lib avutil.lib swresample.lib swscale.lib png16_static ${wxWidgets_LIBRARIES} ${OPENAL_LIBRARY} ${ADDITIONAL_LIBS})
|
||||
else()
|
||||
if(LLVM_FOUND)
|
||||
target_link_libraries(rpcs3 asmjit.a ${wxWidgets_LIBRARIES} ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES})
|
||||
target_link_libraries(rpcs3 libavformat.a libavcodec.a libavutil.a libswresample.a libswscale.a ${ZLIB_LIBRARIES} ${LLVM_LIBS} ${ADDITIONAL_LIBS})
|
||||
target_link_libraries(rpcs3 asmjit.a ${wxWidgets_LIBRARIES} ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES})
|
||||
target_link_libraries(rpcs3 libavformat.a libavcodec.a libavutil.a libswresample.a libswscale.a png16_static ${ZLIB_LIBRARIES} ${LLVM_LIBS} ${ADDITIONAL_LIBS})
|
||||
else()
|
||||
target_link_libraries(rpcs3 asmjit.a ${wxWidgets_LIBRARIES} ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES})
|
||||
target_link_libraries(rpcs3 libavformat.a libavcodec.a libavutil.a libswresample.a libswscale.a ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS})
|
||||
target_link_libraries(rpcs3 asmjit.a ${wxWidgets_LIBRARIES} ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES})
|
||||
target_link_libraries(rpcs3 libavformat.a libavcodec.a libavutil.a libswresample.a libswscale.a png16_static ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
#pragma once
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#include "minidx12/Include/sdkddkver.h" // Use last SDKDDKVer in SDK 10.586 for Win10
|
||||
#include "Emu/Audio/AudioThread.h"
|
||||
|
||||
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) // XAudio2 2.8 and 2.9 available only on Win8+ and Win10.
|
||||
#include "minidx12/Include/xaudio2.h"
|
||||
#else
|
||||
#include "minidx9/Include/XAudio2.h" // XAudio 2.7 for Windows 7 Only
|
||||
#endif
|
||||
|
||||
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN10)
|
||||
#pragma comment(lib,"../minidx12/Lib/xaudio2.lib") // Lib 2.9 for Only Windows 10
|
||||
#elif (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
|
||||
#pragma comment(lib,"../minidx12/Lib/xaudio2_8.lib") // Lib 2.8 for Only Windows 8+
|
||||
#endif
|
||||
#pragma push_macro("_WIN32_WINNT")
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0601 // This is to be sure that correct (2.7) header is included
|
||||
#include "minidx9/Include/XAudio2.h" // XAudio2 2.8 available only on Win8+, used XAudio2 2.7 from dxsdk
|
||||
#pragma pop_macro("_WIN32_WINNT")
|
||||
|
||||
class XAudio2Thread : public AudioThread
|
||||
{
|
||||
|
||||
@@ -73,14 +73,12 @@ void ppu_interpreter::TWI(PPUThread& CPU, ppu_opcode_t op)
|
||||
|
||||
void ppu_interpreter::MFVSCR(PPUThread& CPU, ppu_opcode_t op)
|
||||
{
|
||||
CPU.VPR[op.vd]._u32[0] = CPU.VSCR.VSCR;
|
||||
CPU.VPR[op.vd].clear();
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
void ppu_interpreter::MTVSCR(PPUThread& CPU, ppu_opcode_t op)
|
||||
{
|
||||
CPU.VSCR.VSCR = CPU.VPR[op.vb]._u32[0];
|
||||
CPU.VSCR.X = CPU.VSCR.Y = 0;
|
||||
// ignored (MFVSCR disabled)
|
||||
}
|
||||
|
||||
void ppu_interpreter::VADDCUW(PPUThread& CPU, ppu_opcode_t op)
|
||||
@@ -1698,7 +1696,7 @@ void ppu_interpreter::TW(PPUThread& CPU, ppu_opcode_t op)
|
||||
((u32)a < (u32)b && (op.bo & 0x2)) ||
|
||||
((u32)a >(u32)b && (op.bo & 0x1)))
|
||||
{
|
||||
//throw EXCEPTION("");
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2571,11 +2571,14 @@ private:
|
||||
s32 a = (s32)CPU.GPR[ra];
|
||||
s32 b = (s32)CPU.GPR[rb];
|
||||
|
||||
if ((a < b && (to & 0x10)) ||
|
||||
(a > b && (to & 0x8)) ||
|
||||
(a == b && (to & 0x4)) ||
|
||||
if( (a < b && (to & 0x10)) ||
|
||||
(a > b && (to & 0x8)) ||
|
||||
(a == b && (to & 0x4)) ||
|
||||
((u32)a < (u32)b && (to & 0x2)) ||
|
||||
((u32)a >(u32)b && (to & 0x1)));
|
||||
((u32)a > (u32)b && (to & 0x1)) )
|
||||
{
|
||||
throw EXCEPTION("Trap! (tw 0x%x, r%d, r%d)", to, ra, rb);
|
||||
}
|
||||
}
|
||||
void LVSL(u32 vd, u32 ra, u32 rb) override
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Analysis/Passes.h"
|
||||
@@ -63,10 +64,10 @@ std::unique_ptr<Module> Compiler::create_module(LLVMContext &llvm_context)
|
||||
|
||||
void Compiler::optimise_module(llvm::Module *module)
|
||||
{
|
||||
llvm::legacy::FunctionPassManager fpm(module);
|
||||
llvm::FunctionPassManager fpm(module);
|
||||
fpm.add(createNoAAPass());
|
||||
fpm.add(createBasicAliasAnalysisPass());
|
||||
fpm.add(createTargetTransformInfoWrapperPass(TargetIRAnalysis()));
|
||||
fpm.add(createNoTargetTransformInfoPass());
|
||||
fpm.add(createEarlyCSEPass());
|
||||
fpm.add(createTailCallEliminationPass());
|
||||
fpm.add(createReassociatePass());
|
||||
@@ -77,7 +78,7 @@ void Compiler::optimise_module(llvm::Module *module)
|
||||
fpm.add(createInstructionCombiningPass());
|
||||
fpm.add(new MemoryDependenceAnalysis());
|
||||
fpm.add(createDeadStoreEliminationPass());
|
||||
fpm.add(new LoopInfoWrapperPass());
|
||||
fpm.add(new LoopInfo());
|
||||
fpm.add(new ScalarEvolution());
|
||||
fpm.add(createSLPVectorizerPass());
|
||||
fpm.add(createInstructionCombiningPass());
|
||||
@@ -412,7 +413,7 @@ std::pair<Executable, llvm::ExecutionEngine *> RecompilationEngine::compile(cons
|
||||
.setOptLevel(llvm::CodeGenOpt::Aggressive)
|
||||
.setMCPU("nehalem")
|
||||
.create();
|
||||
module_ptr->setDataLayout(*execution_engine->getDataLayout());
|
||||
module_ptr->setDataLayout(execution_engine->getDataLayout());
|
||||
|
||||
// Translate to machine code
|
||||
execution_engine->finalizeObject();
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push, 0)
|
||||
#endif
|
||||
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
@@ -144,7 +144,7 @@ void Compiler::VADDFP(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VADDSBS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v16i8 = GetVrAsIntVec(va, 8);
|
||||
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
|
||||
auto sum_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_b), { va_v16i8, vb_v16i8 });
|
||||
auto sum_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_b), va_v16i8, vb_v16i8);
|
||||
SetVr(vd, sum_v16i8);
|
||||
|
||||
// TODO: Set VSCR.SAT
|
||||
@@ -153,7 +153,7 @@ void Compiler::VADDSBS(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VADDSHS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto sum_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_w), { va_v8i16, vb_v8i16 });
|
||||
auto sum_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_w), va_v8i16, vb_v8i16);
|
||||
SetVr(vd, sum_v8i16);
|
||||
|
||||
// TODO: Set VSCR.SAT
|
||||
@@ -194,7 +194,7 @@ void Compiler::VADDSWS(u32 vd, u32 va, u32 vb) {
|
||||
auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16));
|
||||
|
||||
// tmp4 is equal to 0xFFFFFFFF if an overflow occured and 0x00000000 otherwise.
|
||||
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), { sum_v16i8, tmp1_v16i8, tmp3_v16i8 });
|
||||
auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), sum_v16i8, tmp1_v16i8, tmp3_v16i8);
|
||||
SetVr(vd, res_v16i8);
|
||||
|
||||
// TODO: Set SAT
|
||||
@@ -210,7 +210,7 @@ void Compiler::VADDUBM(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VADDUBS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v16i8 = GetVrAsIntVec(va, 8);
|
||||
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
|
||||
auto sum_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_b), { va_v16i8, vb_v16i8 });
|
||||
auto sum_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_b), va_v16i8, vb_v16i8);
|
||||
SetVr(vd, sum_v16i8);
|
||||
|
||||
// TODO: Set SAT
|
||||
@@ -226,7 +226,7 @@ void Compiler::VADDUHM(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VADDUHS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto sum_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_w), { va_v8i16, vb_v8i16 });
|
||||
auto sum_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_w), va_v8i16, vb_v8i16);
|
||||
SetVr(vd, sum_v8i16);
|
||||
|
||||
// TODO: Set SAT
|
||||
@@ -305,14 +305,14 @@ void Compiler::VAVGSW(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VAVGUB(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v16i8 = GetVrAsIntVec(va, 8);
|
||||
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
|
||||
auto avg_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_b), { va_v16i8, vb_v16i8 });
|
||||
auto avg_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_b), va_v16i8, vb_v16i8);
|
||||
SetVr(vd, avg_v16i8);
|
||||
}
|
||||
|
||||
void Compiler::VAVGUH(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto avg_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_w), { va_v8i16, vb_v8i16 });
|
||||
auto avg_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_w), va_v8i16, vb_v8i16);
|
||||
SetVr(vd, avg_v8i16);
|
||||
}
|
||||
|
||||
@@ -557,7 +557,7 @@ void Compiler::VCTUXS(u32 vd, u32 uimm5, u32 vb) {
|
||||
vb_v4f32 = m_ir_builder->CreateFMul(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 1 << uimm5)));
|
||||
}
|
||||
|
||||
auto res_v4f32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), { vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0)) });
|
||||
auto res_v4f32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0)));
|
||||
auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0xFFFFFFFFu)));
|
||||
auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4));
|
||||
auto res_v4i32 = m_ir_builder->CreateFPToUI(res_v4f32, VectorType::get(m_ir_builder->getInt32Ty(), 4));
|
||||
@@ -569,8 +569,8 @@ void Compiler::VCTUXS(u32 vd, u32 uimm5, u32 vb) {
|
||||
|
||||
void Compiler::VEXPTEFP(u32 vd, u32 vb) {
|
||||
auto vb_v4f32 = GetVrAsFloatVec(vb);
|
||||
auto res_v4f32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::pow, VectorType::get(m_ir_builder->getFloatTy(), 4)),
|
||||
{ m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 2.0f)), vb_v4f32 });
|
||||
auto res_v4f32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::pow, VectorType::get(m_ir_builder->getFloatTy(), 4)),
|
||||
m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 2.0f)), vb_v4f32);
|
||||
SetVr(vd, res_v4f32);
|
||||
}
|
||||
|
||||
@@ -584,56 +584,56 @@ void Compiler::VMADDFP(u32 vd, u32 va, u32 vc, u32 vb) {
|
||||
auto va_v4f32 = GetVrAsFloatVec(va);
|
||||
auto vb_v4f32 = GetVrAsFloatVec(vb);
|
||||
auto vc_v4f32 = GetVrAsFloatVec(vc);
|
||||
auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), { va_v4f32, vc_v4f32, vb_v4f32 });
|
||||
auto res_v4f32 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), va_v4f32, vc_v4f32, vb_v4f32);
|
||||
SetVr(vd, res_v4f32);
|
||||
}
|
||||
|
||||
void Compiler::VMAXFP(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v4f32 = GetVrAsFloatVec(va);
|
||||
auto vb_v4f32 = GetVrAsFloatVec(vb);
|
||||
auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), { va_v4f32, vb_v4f32 });
|
||||
auto res_v4f32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), va_v4f32, vb_v4f32);
|
||||
SetVr(vd, res_v4f32);
|
||||
}
|
||||
|
||||
void Compiler::VMAXSB(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v16i8 = GetVrAsIntVec(va, 8);
|
||||
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
|
||||
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsb), { va_v16i8, vb_v16i8 });
|
||||
auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsb), va_v16i8, vb_v16i8);
|
||||
SetVr(vd, res_v16i8);
|
||||
}
|
||||
|
||||
void Compiler::VMAXSH(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxs_w), { va_v8i16, vb_v8i16 });
|
||||
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxs_w), va_v8i16, vb_v8i16);
|
||||
SetVr(vd, res_v8i16);
|
||||
}
|
||||
|
||||
void Compiler::VMAXSW(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v4i32 = GetVrAsIntVec(va, 32);
|
||||
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
|
||||
auto res_v4i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsd), { va_v4i32, vb_v4i32 });
|
||||
auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsd), va_v4i32, vb_v4i32);
|
||||
SetVr(vd, res_v4i32);
|
||||
}
|
||||
|
||||
void Compiler::VMAXUB(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v16i8 = GetVrAsIntVec(va, 8);
|
||||
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
|
||||
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxu_b), { va_v16i8, vb_v16i8 });
|
||||
auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxu_b), va_v16i8, vb_v16i8);
|
||||
SetVr(vd, res_v16i8);
|
||||
}
|
||||
|
||||
void Compiler::VMAXUH(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxuw), { va_v8i16, vb_v8i16 });
|
||||
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxuw), va_v8i16, vb_v8i16);
|
||||
SetVr(vd, res_v8i16);
|
||||
}
|
||||
|
||||
void Compiler::VMAXUW(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v4i32 = GetVrAsIntVec(va, 32);
|
||||
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
|
||||
auto res_v4i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxud), { va_v4i32, vb_v4i32 });
|
||||
auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxud), va_v4i32, vb_v4i32);
|
||||
SetVr(vd, res_v4i32);
|
||||
}
|
||||
|
||||
@@ -652,7 +652,7 @@ void Compiler::VMHADDSHS(u32 vd, u32 va, u32 vb, u32 vc) {
|
||||
auto res1_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32));
|
||||
u32 mask2_v4i32[4] = { 4, 5, 6, 7 };
|
||||
auto res2_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32));
|
||||
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), { res1_v4i32, res2_v4i32 });
|
||||
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), res1_v4i32, res2_v4i32);
|
||||
SetVr(vd, res_v8i16);
|
||||
|
||||
// TODO: Set VSCR.SAT
|
||||
@@ -674,7 +674,7 @@ void Compiler::VMHRADDSHS(u32 vd, u32 va, u32 vb, u32 vc) {
|
||||
auto res1_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32));
|
||||
u32 mask2_v4i32[4] = { 4, 5, 6, 7 };
|
||||
auto res2_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32));
|
||||
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), { res1_v4i32, res2_v4i32 });
|
||||
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), res1_v4i32, res2_v4i32);
|
||||
SetVr(vd, res_v8i16);
|
||||
|
||||
// TODO: Set VSCR.SAT
|
||||
@@ -683,49 +683,49 @@ void Compiler::VMHRADDSHS(u32 vd, u32 va, u32 vb, u32 vc) {
|
||||
void Compiler::VMINFP(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v4f32 = GetVrAsFloatVec(va);
|
||||
auto vb_v4f32 = GetVrAsFloatVec(vb);
|
||||
auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_min_ps), { va_v4f32, vb_v4f32 });
|
||||
auto res_v4f32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_min_ps), va_v4f32, vb_v4f32);
|
||||
SetVr(vd, res_v4f32);
|
||||
}
|
||||
|
||||
void Compiler::VMINSB(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v16i8 = GetVrAsIntVec(va, 8);
|
||||
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
|
||||
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsb), { va_v16i8, vb_v16i8 });
|
||||
auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsb), va_v16i8, vb_v16i8);
|
||||
SetVr(vd, res_v16i8);
|
||||
}
|
||||
|
||||
void Compiler::VMINSH(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmins_w), { va_v8i16, vb_v8i16 });
|
||||
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmins_w), va_v8i16, vb_v8i16);
|
||||
SetVr(vd, res_v8i16);
|
||||
}
|
||||
|
||||
void Compiler::VMINSW(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v4i32 = GetVrAsIntVec(va, 32);
|
||||
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
|
||||
auto res_v4i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsd), { va_v4i32, vb_v4i32 });
|
||||
auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsd), va_v4i32, vb_v4i32);
|
||||
SetVr(vd, res_v4i32);
|
||||
}
|
||||
|
||||
void Compiler::VMINUB(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v16i8 = GetVrAsIntVec(va, 8);
|
||||
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
|
||||
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pminu_b), { va_v16i8, vb_v16i8 });
|
||||
auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pminu_b), va_v16i8, vb_v16i8);
|
||||
SetVr(vd, res_v16i8);
|
||||
}
|
||||
|
||||
void Compiler::VMINUH(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), { va_v8i16, vb_v8i16 });
|
||||
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), va_v8i16, vb_v8i16);
|
||||
SetVr(vd, res_v8i16);
|
||||
}
|
||||
|
||||
void Compiler::VMINUW(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v4i32 = GetVrAsIntVec(va, 32);
|
||||
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
|
||||
auto res_v4i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), { va_v4i32, vb_v4i32 });
|
||||
auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), va_v4i32, vb_v4i32);
|
||||
SetVr(vd, res_v4i32);
|
||||
}
|
||||
|
||||
@@ -822,7 +822,7 @@ void Compiler::VMSUMSHM(u32 vd, u32 va, u32 vb, u32 vc) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto vc_v4i32 = GetVrAsIntVec(vc, 32);
|
||||
auto res_v4i32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), { va_v8i16, vb_v8i16 });
|
||||
auto res_v4i32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), va_v8i16, vb_v8i16);
|
||||
res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32);
|
||||
SetVr(vd, res_v4i32);
|
||||
}
|
||||
@@ -831,7 +831,7 @@ void Compiler::VMSUMSHS(u32 vd, u32 va, u32 vb, u32 vc) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto vc_v4i32 = GetVrAsIntVec(vc, 32);
|
||||
auto res_v4i32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), { va_v8i16, vb_v8i16 });
|
||||
auto res_v4i32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), va_v8i16, vb_v8i16);
|
||||
|
||||
auto tmp1_v4i32 = m_ir_builder->CreateLShr(vc_v4i32, 31);
|
||||
tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF)));
|
||||
@@ -844,7 +844,7 @@ void Compiler::VMSUMSHS(u32 vd, u32 va, u32 vb, u32 vc) {
|
||||
tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32);
|
||||
tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31);
|
||||
auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16));
|
||||
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), { sum_v16i8, tmp1_v16i8, tmp3_v16i8 });
|
||||
auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), sum_v16i8, tmp1_v16i8, tmp3_v16i8);
|
||||
SetVr(vd, res_v16i8);
|
||||
|
||||
// TODO: Set VSCR.SAT
|
||||
@@ -1015,7 +1015,7 @@ void Compiler::VNMSUBFP(u32 vd, u32 va, u32 vc, u32 vb) {
|
||||
auto vb_v4f32 = GetVrAsFloatVec(vb);
|
||||
auto vc_v4f32 = GetVrAsFloatVec(vc);
|
||||
vc_v4f32 = m_ir_builder->CreateFNeg(vc_v4f32);
|
||||
auto res_v4f32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), { va_v4f32, vc_v4f32, vb_v4f32 });
|
||||
auto res_v4f32 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), va_v4f32, vc_v4f32, vb_v4f32);
|
||||
SetVr(vd, res_v4f32);
|
||||
}
|
||||
|
||||
@@ -1044,13 +1044,13 @@ void Compiler::VPERM(u32 vd, u32 va, u32 vb, u32 vc) {
|
||||
|
||||
auto fifteen_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(15));
|
||||
auto vc_le15_v16i8 = m_ir_builder->CreateSub(fifteen_v16i8, vc_v16i8);
|
||||
auto res_va_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), { va_v16i8, vc_le15_v16i8 });
|
||||
auto res_va_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), va_v16i8, vc_le15_v16i8);
|
||||
|
||||
auto vc_gt15_v16i8 = m_ir_builder->CreateSub(thrity_one_v16i8, vc_v16i8);
|
||||
auto cmp_i1 = m_ir_builder->CreateICmpUGT(vc_gt15_v16i8, fifteen_v16i8);
|
||||
auto cmp_i8 = m_ir_builder->CreateSExt(cmp_i1, VectorType::get(m_ir_builder->getInt8Ty(), 16));
|
||||
vc_gt15_v16i8 = m_ir_builder->CreateOr(cmp_i8, vc_gt15_v16i8);
|
||||
auto res_vb_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), { vb_v16i8, vc_gt15_v16i8 });
|
||||
auto res_vb_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), vb_v16i8, vc_gt15_v16i8);
|
||||
|
||||
auto res_v16i8 = m_ir_builder->CreateOr(res_vb_v16i8, res_va_v16i8);
|
||||
SetVr(vd, res_v16i8);
|
||||
@@ -1093,7 +1093,7 @@ void Compiler::VPKPX(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VPKSHSS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packsswb_128), { vb_v8i16, va_v8i16 });
|
||||
auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packsswb_128), vb_v8i16, va_v8i16);
|
||||
SetVr(vd, res_v16i8);
|
||||
|
||||
// TODO: VSCR.SAT
|
||||
@@ -1102,7 +1102,7 @@ void Compiler::VPKSHSS(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VPKSHUS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packuswb_128), { vb_v8i16, va_v8i16 });
|
||||
auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packuswb_128), vb_v8i16, va_v8i16);
|
||||
SetVr(vd, res_v16i8);
|
||||
|
||||
// TODO: VSCR.SAT
|
||||
@@ -1111,7 +1111,7 @@ void Compiler::VPKSHUS(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VPKSWSS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v4i32 = GetVrAsIntVec(va, 32);
|
||||
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
|
||||
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), { vb_v4i32, va_v4i32 });
|
||||
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), vb_v4i32, va_v4i32);
|
||||
SetVr(vd, res_v8i16);
|
||||
|
||||
// TODO: VSCR.SAT
|
||||
@@ -1120,7 +1120,7 @@ void Compiler::VPKSWSS(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VPKSWUS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v4i32 = GetVrAsIntVec(va, 32);
|
||||
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
|
||||
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_packusdw), { vb_v4i32, va_v4i32 });
|
||||
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_packusdw), vb_v4i32, va_v4i32);
|
||||
SetVr(vd, res_v8i16);
|
||||
|
||||
// TODO: VSCR.SAT
|
||||
@@ -1138,8 +1138,8 @@ void Compiler::VPKUHUM(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VPKUHUS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
va_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), { va_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF)) });
|
||||
vb_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), { vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF)) });
|
||||
va_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), va_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF)));
|
||||
vb_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF)));
|
||||
auto va_v16i8 = m_ir_builder->CreateBitCast(va_v8i16, VectorType::get(m_ir_builder->getInt8Ty(), 16));
|
||||
auto vb_v16i8 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt8Ty(), 16));
|
||||
|
||||
@@ -1162,8 +1162,8 @@ void Compiler::VPKUWUM(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VPKUWUS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v4i32 = GetVrAsIntVec(va, 32);
|
||||
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
|
||||
va_v4i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), { va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF)) });
|
||||
vb_v4i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), { vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF)) });
|
||||
va_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF)));
|
||||
vb_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF)));
|
||||
auto va_v8i16 = m_ir_builder->CreateBitCast(va_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8));
|
||||
auto vb_v8i16 = m_ir_builder->CreateBitCast(vb_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8));
|
||||
|
||||
@@ -1434,7 +1434,7 @@ void Compiler::VSUBFP(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VSUBSBS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v16i8 = GetVrAsIntVec(va, 8);
|
||||
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
|
||||
auto diff_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_b), { va_v16i8, vb_v16i8 });
|
||||
auto diff_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_b), va_v16i8, vb_v16i8);
|
||||
SetVr(vd, diff_v16i8);
|
||||
|
||||
// TODO: Set VSCR.SAT
|
||||
@@ -1443,7 +1443,7 @@ void Compiler::VSUBSBS(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VSUBSHS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto diff_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_w), { va_v8i16, vb_v8i16 });
|
||||
auto diff_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_w), va_v8i16, vb_v8i16);
|
||||
SetVr(vd, diff_v8i16);
|
||||
|
||||
// TODO: Set VSCR.SAT
|
||||
@@ -1474,7 +1474,7 @@ void Compiler::VSUBSWS(u32 vd, u32 va, u32 vb) {
|
||||
auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16));
|
||||
|
||||
// tmp4 is equal to 0xFFFFFFFF if an overflow occured and 0x00000000 otherwise.
|
||||
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), { diff_v16i8, tmp1_v16i8, tmp3_v16i8 });
|
||||
auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), diff_v16i8, tmp1_v16i8, tmp3_v16i8);
|
||||
SetVr(vd, res_v16i8);
|
||||
|
||||
// TODO: Set SAT
|
||||
@@ -1490,7 +1490,7 @@ void Compiler::VSUBUBM(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VSUBUBS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v16i8 = GetVrAsIntVec(va, 8);
|
||||
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
|
||||
auto diff_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_b), {va_v16i8, vb_v16i8});
|
||||
auto diff_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_b), va_v16i8, vb_v16i8);
|
||||
SetVr(vd, diff_v16i8);
|
||||
|
||||
// TODO: Set SAT
|
||||
@@ -1506,7 +1506,7 @@ void Compiler::VSUBUHM(u32 vd, u32 va, u32 vb) {
|
||||
void Compiler::VSUBUHS(u32 vd, u32 va, u32 vb) {
|
||||
auto va_v8i16 = GetVrAsIntVec(va, 16);
|
||||
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
|
||||
auto diff_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_w), { va_v8i16, vb_v8i16 });
|
||||
auto diff_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_w), va_v8i16, vb_v8i16);
|
||||
SetVr(vd, diff_v8i16);
|
||||
|
||||
// TODO: Set SAT
|
||||
@@ -1744,7 +1744,7 @@ void Compiler::SUBFIC(u32 rd, u32 ra, s32 simm16) {
|
||||
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
ra_i64 = m_ir_builder->CreateNeg(ra_i64); // simpler way of doing ~ra + 1
|
||||
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, m_ir_builder->getInt64((s64)simm16) });
|
||||
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, m_ir_builder->getInt64((s64)simm16));
|
||||
auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
auto is_zero = m_ir_builder->CreateICmpEQ(ra_i64, m_ir_builder->getInt64(0)); // if ra is zero when ~ra + 1 = 0 sets overflow bit
|
||||
@@ -1785,7 +1785,7 @@ void Compiler::ADDIC(u32 rd, u32 ra, s32 simm16) {
|
||||
USE_INTERP_IF_REQUESTED(ADDIC, m_ir_builder->getInt32(rd), m_ir_builder->getInt32(ra), m_ir_builder->getInt32(simm16));
|
||||
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { m_ir_builder->getInt64((s64)simm16), ra_i64 });
|
||||
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), m_ir_builder->getInt64((s64)simm16), ra_i64);
|
||||
auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
SetGpr(rd, sum_i64);
|
||||
@@ -2337,7 +2337,7 @@ void Compiler::SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
ra_i64 = m_ir_builder->CreateNeg(ra_i64);
|
||||
auto rb_i64 = GetGpr(rb);
|
||||
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, rb_i64 });
|
||||
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64);
|
||||
auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
SetGpr(rd, diff_i64);
|
||||
@@ -2356,7 +2356,7 @@ void Compiler::SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) {
|
||||
void Compiler::ADDC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
auto rb_i64 = GetGpr(rb);
|
||||
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, rb_i64 });
|
||||
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64);
|
||||
auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
SetGpr(rd, sum_i64);
|
||||
@@ -2468,7 +2468,7 @@ void Compiler::SLW(u32 ra, u32 rs, u32 rb, u32 rc) {
|
||||
|
||||
void Compiler::CNTLZW(u32 ra, u32 rs, u32 rc) {
|
||||
auto rs_i32 = GetGpr(rs, 32);
|
||||
auto res_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt32Ty()), { rs_i32, m_ir_builder->getInt1(false) });
|
||||
auto res_i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt32Ty()), rs_i32, m_ir_builder->getInt1(false));
|
||||
auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty());
|
||||
SetGpr(ra, res_i64);
|
||||
|
||||
@@ -2618,7 +2618,7 @@ void Compiler::LWZUX(u32 rd, u32 ra, u32 rb) {
|
||||
|
||||
void Compiler::CNTLZD(u32 ra, u32 rs, u32 rc) {
|
||||
auto rs_i64 = GetGpr(rs);
|
||||
auto res_i64 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt64Ty()), { rs_i64, m_ir_builder->getInt1(false) });
|
||||
auto res_i64 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt64Ty()), rs_i64, m_ir_builder->getInt1(false));
|
||||
SetGpr(ra, res_i64);
|
||||
|
||||
if (rc) {
|
||||
@@ -2793,10 +2793,10 @@ void Compiler::SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
auto rb_i64 = GetGpr(rb);
|
||||
ra_i64 = m_ir_builder->CreateNot(ra_i64);
|
||||
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), {ra_i64, ca_i64 });
|
||||
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64);
|
||||
auto res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { res_i64, rb_i64 });
|
||||
res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, rb_i64);
|
||||
res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1);
|
||||
@@ -2817,10 +2817,10 @@ void Compiler::ADDE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) {
|
||||
auto ca_i64 = GetXerCa();
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
auto rb_i64 = GetGpr(rb);
|
||||
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, ca_i64 });
|
||||
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64);
|
||||
auto res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { res_i64, rb_i64 });
|
||||
res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, rb_i64);
|
||||
res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1);
|
||||
@@ -2954,7 +2954,7 @@ void Compiler::STVEWX(u32 vs, u32 ra, u32 rb) {
|
||||
void Compiler::ADDZE(u32 rd, u32 ra, u32 oe, u32 rc) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
auto ca_i64 = GetXerCa();
|
||||
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, ca_i64 });
|
||||
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64);
|
||||
auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
SetGpr(rd, sum_i64);
|
||||
@@ -2974,7 +2974,7 @@ void Compiler::SUBFZE(u32 rd, u32 ra, u32 oe, u32 rc) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
ra_i64 = m_ir_builder->CreateNot(ra_i64);
|
||||
auto ca_i64 = GetXerCa();
|
||||
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, ca_i64 });
|
||||
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64);
|
||||
auto res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
SetGpr(rd, res_i64);
|
||||
@@ -3035,10 +3035,10 @@ void Compiler::SUBFME(u32 rd, u32 ra, u32 oe, u32 rc) {
|
||||
auto ca_i64 = GetXerCa();
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
ra_i64 = m_ir_builder->CreateNot(ra_i64);
|
||||
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, ca_i64 });
|
||||
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64);
|
||||
auto res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { res_i64, m_ir_builder->getInt64((s64)-1) });
|
||||
res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, m_ir_builder->getInt64((s64)-1));
|
||||
res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1);
|
||||
@@ -3074,10 +3074,10 @@ void Compiler::MULLD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) {
|
||||
void Compiler::ADDME(u32 rd, u32 ra, u32 oe, u32 rc) {
|
||||
auto ca_i64 = GetXerCa();
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, ca_i64 });
|
||||
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64);
|
||||
auto res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { res_i64, m_ir_builder->getInt64((s64)-1) });
|
||||
res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, m_ir_builder->getInt64((s64)-1));
|
||||
res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
|
||||
auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
|
||||
auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1);
|
||||
@@ -3663,8 +3663,8 @@ void Compiler::STVLX(u32 vs, u32 ra, u32 rb) {
|
||||
auto vs_i8_ptr = m_ir_builder->CreateBitCast(vs_i128_ptr, m_ir_builder->getInt8PtrTy());
|
||||
|
||||
Type * types[3] = { m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt64Ty() };
|
||||
m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types),
|
||||
{ addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false) });
|
||||
m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types),
|
||||
addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false));
|
||||
}
|
||||
|
||||
void Compiler::STDBRX(u32 rs, u32 ra, u32 rb) {
|
||||
@@ -3724,8 +3724,8 @@ void Compiler::STVRX(u32 vs, u32 ra, u32 rb) {
|
||||
vs_i8_ptr = m_ir_builder->CreateGEP(vs_i8_ptr, index_i64);
|
||||
|
||||
Type * types[3] = { m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt64Ty() };
|
||||
m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types),
|
||||
{ addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false) });
|
||||
m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types),
|
||||
addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false));
|
||||
}
|
||||
|
||||
void Compiler::STFSUX(u32 frs, u32 ra, u32 rb) {
|
||||
@@ -3994,8 +3994,8 @@ void Compiler::DCBZ(u32 ra, u32 rb) {
|
||||
auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy());
|
||||
|
||||
std::vector<Type *> types = { (Type *)m_ir_builder->getInt8PtrTy(), (Type *)m_ir_builder->getInt32Ty() };
|
||||
m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::memset, types),
|
||||
{ addr_i8_ptr, m_ir_builder->getInt8(0), m_ir_builder->getInt32(128), m_ir_builder->getInt32(128), m_ir_builder->getInt1(true) });
|
||||
m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memset, types),
|
||||
addr_i8_ptr, m_ir_builder->getInt8(0), m_ir_builder->getInt32(128), m_ir_builder->getInt32(128), m_ir_builder->getInt1(true));
|
||||
}
|
||||
|
||||
void Compiler::LWZ(u32 rd, u32 ra, s32 d) {
|
||||
@@ -4397,7 +4397,7 @@ void Compiler::FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
|
||||
auto ra_f64 = GetFpr(fra);
|
||||
auto rb_f64 = GetFpr(frb);
|
||||
auto rc_f64 = GetFpr(frc);
|
||||
auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
|
||||
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
|
||||
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
|
||||
SetFpr(frd, res_f32);
|
||||
|
||||
@@ -4414,7 +4414,7 @@ void Compiler::FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
|
||||
auto rb_f64 = GetFpr(frb);
|
||||
auto rc_f64 = GetFpr(frc);
|
||||
rb_f64 = m_ir_builder->CreateFNeg(rb_f64);
|
||||
auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
|
||||
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
|
||||
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
|
||||
SetFpr(frd, res_f32);
|
||||
|
||||
@@ -4431,7 +4431,7 @@ void Compiler::FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
|
||||
auto rb_f64 = GetFpr(frb);
|
||||
auto rc_f64 = GetFpr(frc);
|
||||
rb_f64 = m_ir_builder->CreateFNeg(rb_f64);
|
||||
auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
|
||||
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
|
||||
res_f64 = m_ir_builder->CreateFNeg(res_f64);
|
||||
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
|
||||
SetFpr(frd, res_f32);
|
||||
@@ -4448,7 +4448,7 @@ void Compiler::FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
|
||||
auto ra_f64 = GetFpr(fra);
|
||||
auto rb_f64 = GetFpr(frb);
|
||||
auto rc_f64 = GetFpr(frc);
|
||||
auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
|
||||
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
|
||||
res_f64 = m_ir_builder->CreateFNeg(res_f64);
|
||||
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
|
||||
SetFpr(frd, res_f32);
|
||||
@@ -4746,7 +4746,7 @@ void Compiler::FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
|
||||
auto rb_f64 = GetFpr(frb);
|
||||
auto rc_f64 = GetFpr(frc);
|
||||
rb_f64 = m_ir_builder->CreateFNeg(rb_f64);
|
||||
auto res_f64 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
|
||||
auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
|
||||
SetFpr(frd, res_f64);
|
||||
|
||||
if (rc) {
|
||||
@@ -4761,7 +4761,7 @@ void Compiler::FMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
|
||||
auto ra_f64 = GetFpr(fra);
|
||||
auto rb_f64 = GetFpr(frb);
|
||||
auto rc_f64 = GetFpr(frc);
|
||||
auto res_f64 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
|
||||
auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
|
||||
SetFpr(frd, res_f64);
|
||||
|
||||
if (rc) {
|
||||
@@ -4777,7 +4777,7 @@ void Compiler::FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
|
||||
auto rb_f64 = GetFpr(frb);
|
||||
auto rc_f64 = GetFpr(frc);
|
||||
rc_f64 = m_ir_builder->CreateFNeg(rc_f64);
|
||||
auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
|
||||
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
|
||||
SetFpr(frd, res_f64);
|
||||
|
||||
if (rc) {
|
||||
@@ -4794,7 +4794,7 @@ void Compiler::FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
|
||||
auto rc_f64 = GetFpr(frc);
|
||||
rb_f64 = m_ir_builder->CreateFNeg(rb_f64);
|
||||
rc_f64 = m_ir_builder->CreateFNeg(rc_f64);
|
||||
auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
|
||||
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
|
||||
SetFpr(frd, res_f64);
|
||||
|
||||
if (rc) {
|
||||
@@ -4983,10 +4983,10 @@ Value * Compiler::GetBit(Value * val, u32 n) {
|
||||
|
||||
#ifdef PPU_LLVM_RECOMPILER_USE_BMI
|
||||
if (val->getType()->isIntegerTy(32)) {
|
||||
bit = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32(1 << (31 - n)));
|
||||
bit = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32(1 << (31 - n)));
|
||||
}
|
||||
else if (val->getType()->isIntegerTy(64)) {
|
||||
bit = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)1 << (63 - n)));
|
||||
bit = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)1 << (63 - n)));
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
@@ -5030,10 +5030,10 @@ Value * Compiler::GetNibble(Value * val, u32 n) {
|
||||
|
||||
#ifdef PPU_LLVM_RECOMPILER_USE_BMI
|
||||
if (val->getType()->isIntegerTy(32)) {
|
||||
nibble = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32((u64)0xF << ((7 - n) * 4)));
|
||||
nibble = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32((u64)0xF << ((7 - n) * 4)));
|
||||
}
|
||||
else if (val->getType()->isIntegerTy(64)) {
|
||||
nibble = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)0xF << ((15 - n) * 4)));
|
||||
nibble = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)0xF << ((15 - n) * 4)));
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
@@ -5417,7 +5417,7 @@ void Compiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_i32, bool
|
||||
// Function *fn = m_module->getFunction(fmt::format("function_0x%08X", target_address));
|
||||
llvm::Value *execStatus;
|
||||
// if (fn)
|
||||
// execStatus = m_ir_builder->CreateCall(fn, {m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0) });
|
||||
// execStatus = m_ir_builder->CreateCall2(fn, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0));
|
||||
// else
|
||||
execStatus = Call<u32>("execute_unknown_function", m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0));
|
||||
|
||||
@@ -5451,7 +5451,7 @@ void Compiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_i32, bool
|
||||
else if (lk) {
|
||||
BasicBlock *next_block = GetBasicBlockFromAddress(m_state.current_instruction_address + 4);
|
||||
|
||||
llvm::Value *execStatus = m_ir_builder->CreateCall(m_execute_unknown_function, {m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0)});
|
||||
llvm::Value *execStatus = m_ir_builder->CreateCall2(m_execute_unknown_function, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0));
|
||||
|
||||
llvm::BasicBlock *cputhreadexitblock = GetBasicBlockFromAddress(m_state.current_instruction_address, "early_exit");
|
||||
llvm::Value *isCPUThreadExit = m_ir_builder->CreateICmpEQ(execStatus, m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException));
|
||||
|
||||
@@ -916,7 +916,7 @@ void spu_recompiler::BISL(spu_opcode_t op)
|
||||
|
||||
void spu_recompiler::IRET(spu_opcode_t op)
|
||||
{
|
||||
//throw EXCEPTION("Unimplemented instruction");
|
||||
throw EXCEPTION("Unimplemented instruction");
|
||||
}
|
||||
|
||||
void spu_recompiler::BISLED(spu_opcode_t op)
|
||||
|
||||
@@ -17,18 +17,45 @@ struct vfsStream
|
||||
|
||||
virtual u64 Write(const void* src, u64 count) = 0;
|
||||
|
||||
template<typename T> force_inline bool SWrite(const T& data, u64 count = sizeof(T))
|
||||
template<typename T>
|
||||
force_inline bool SWrite(const T& data, u64 count = sizeof(T))
|
||||
{
|
||||
return Write(&data, count) == count;
|
||||
}
|
||||
|
||||
virtual u64 Read(void* dst, u64 count) = 0;
|
||||
|
||||
template<typename T> force_inline bool SRead(T& data, u64 count = sizeof(T))
|
||||
template<typename T>
|
||||
force_inline bool SRead(T& data, u64 count = sizeof(T))
|
||||
{
|
||||
return Read(&data, count) == count;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool VWrite(const std::vector<T>& vec)
|
||||
{
|
||||
return IsOpened() && Write(vec.data(), vec.size() * sizeof(T)) == vec.size() * sizeof(T);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> VRead()
|
||||
{
|
||||
std::vector<T> result;
|
||||
if (IsOpened() == false)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result.resize(GetSize() / sizeof(T));
|
||||
|
||||
if (Seek(0) == -1 || Read(result.data(), result.size() * sizeof(T)) != result.size() * sizeof(T))
|
||||
{
|
||||
result.clear();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual u64 Seek(s64 offset, fs::seek_mode whence = fs::seek_set) = 0;
|
||||
|
||||
virtual u64 Tell() const = 0;
|
||||
|
||||
@@ -807,7 +807,7 @@ namespace vm
|
||||
{
|
||||
if (used > this->size)
|
||||
{
|
||||
//throw EXCEPTION("Unexpected memory amount used (0x%x)", used);
|
||||
throw EXCEPTION("Unexpected memory amount used (0x%x)", used);
|
||||
}
|
||||
|
||||
if (used + size > this->size)
|
||||
|
||||
@@ -335,7 +335,7 @@ public:
|
||||
u32 ctrl = (vmfprog.outputFromH0 ? 0 : 0x40) | (vmfprog.depthReplace ? 0xe : 0);
|
||||
std::vector<texture_dimension> td;
|
||||
RSXFragmentProgram prog;
|
||||
prog.size = 0, prog.addr = ptr + vmprog.ucode, prog.offset = 0, prog.ctrl = ctrl;
|
||||
prog.size = 0, prog.addr = vm::base(ptr + vmprog.ucode), prog.offset = 0, prog.ctrl = ctrl;
|
||||
GLFragmentDecompilerThread(m_glsl_shader, param_array, prog, size).Task();
|
||||
vm::close();
|
||||
}
|
||||
|
||||
@@ -30,32 +30,29 @@ namespace
|
||||
|
||||
void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_t index, const rsx::data_array_format_info &vertex_array_desc)
|
||||
{
|
||||
assert(vertex_array_desc.size > 0);
|
||||
|
||||
if (vertex_array_desc.frequency > 1)
|
||||
LOG_ERROR(RSX, "%s: frequency is not null (%d, index=%d)", __FUNCTION__, vertex_array_desc.frequency, index);
|
||||
Expects(vertex_array_desc.size > 0);
|
||||
|
||||
u32 base_offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET];
|
||||
u32 offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index];
|
||||
u32 address = rsx::get_address(offset & 0x7fffffff, offset >> 31);
|
||||
u32 address = base_offset + rsx::get_address(offset & 0x7fffffff, offset >> 31);
|
||||
|
||||
u32 element_size = rsx::get_vertex_type_size_on_host(vertex_array_desc.type, vertex_array_desc.size);
|
||||
|
||||
u32 base_offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET];
|
||||
u32 base_index = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX];
|
||||
|
||||
for (u32 i = 0; i < count; ++i)
|
||||
{
|
||||
auto src = vm::ps3::_ptr<const u8>(address + base_offset + vertex_array_desc.stride * (first + i + base_index));
|
||||
auto src = vm::ps3::_ptr<const u8>(address + vertex_array_desc.stride * (first + i + base_index));
|
||||
u8* dst = (u8*)buffer + i * element_size;
|
||||
|
||||
switch (vertex_array_desc.type)
|
||||
{
|
||||
case Vertex_base_type::ub:
|
||||
case rsx::vertex_base_type::ub:
|
||||
memcpy(dst, src, vertex_array_desc.size);
|
||||
break;
|
||||
|
||||
case Vertex_base_type::s1:
|
||||
case Vertex_base_type::sf:
|
||||
case rsx::vertex_base_type::s1:
|
||||
case rsx::vertex_base_type::sf:
|
||||
{
|
||||
auto* c_src = (const be_t<u16>*)src;
|
||||
u16* c_dst = (u16*)dst;
|
||||
@@ -65,13 +62,13 @@ void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_
|
||||
*c_dst++ = *c_src++;
|
||||
}
|
||||
if (vertex_array_desc.size * sizeof(u16) < element_size)
|
||||
*c_dst++ = 0x3800;
|
||||
*c_dst++ = 0x3c00;
|
||||
break;
|
||||
}
|
||||
|
||||
case Vertex_base_type::f:
|
||||
case Vertex_base_type::s32k:
|
||||
case Vertex_base_type::ub256:
|
||||
case rsx::vertex_base_type::f:
|
||||
case rsx::vertex_base_type::s32k:
|
||||
case rsx::vertex_base_type::ub256:
|
||||
{
|
||||
auto* c_src = (const be_t<u32>*)src;
|
||||
u32* c_dst = (u32*)dst;
|
||||
@@ -82,7 +79,7 @@ void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Vertex_base_type::cmp:
|
||||
case rsx::vertex_base_type::cmp:
|
||||
{
|
||||
auto* c_src = (const be_t<u32>*)src;
|
||||
const auto& decoded_vector = decode_cmp_vector(*c_src);
|
||||
@@ -244,21 +241,21 @@ std::tuple<T, T> expand_indexed_quads(gsl::span<to_be_t<const T>> src, gsl::span
|
||||
}
|
||||
|
||||
// Only handle quads and triangle fan now
|
||||
bool is_primitive_native(Primitive_type m_draw_mode)
|
||||
bool is_primitive_native(rsx::primitive_type draw_mode)
|
||||
{
|
||||
switch (m_draw_mode)
|
||||
switch (draw_mode)
|
||||
{
|
||||
case Primitive_type::points:
|
||||
case Primitive_type::lines:
|
||||
case Primitive_type::line_loop:
|
||||
case Primitive_type::line_strip:
|
||||
case Primitive_type::triangles:
|
||||
case Primitive_type::triangle_strip:
|
||||
case Primitive_type::quad_strip:
|
||||
case rsx::primitive_type::points:
|
||||
case rsx::primitive_type::lines:
|
||||
case rsx::primitive_type::line_loop:
|
||||
case rsx::primitive_type::line_strip:
|
||||
case rsx::primitive_type::triangles:
|
||||
case rsx::primitive_type::triangle_strip:
|
||||
case rsx::primitive_type::quad_strip:
|
||||
return true;
|
||||
case Primitive_type::polygon:
|
||||
case Primitive_type::triangle_fan:
|
||||
case Primitive_type::quads:
|
||||
case rsx::primitive_type::polygon:
|
||||
case rsx::primitive_type::triangle_fan:
|
||||
case rsx::primitive_type::quads:
|
||||
return false;
|
||||
}
|
||||
throw new EXCEPTION("Wrong primitive type");
|
||||
@@ -269,41 +266,41 @@ bool is_primitive_native(Primitive_type m_draw_mode)
|
||||
* see http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/polygon-triangulation-r3334
|
||||
*/
|
||||
|
||||
size_t get_index_count(Primitive_type m_draw_mode, unsigned initial_index_count)
|
||||
size_t get_index_count(rsx::primitive_type draw_mode, unsigned initial_index_count)
|
||||
{
|
||||
// Index count
|
||||
if (is_primitive_native(m_draw_mode))
|
||||
if (is_primitive_native(draw_mode))
|
||||
return initial_index_count;
|
||||
|
||||
switch (m_draw_mode)
|
||||
switch (draw_mode)
|
||||
{
|
||||
case Primitive_type::polygon:
|
||||
case Primitive_type::triangle_fan:
|
||||
case rsx::primitive_type::polygon:
|
||||
case rsx::primitive_type::triangle_fan:
|
||||
return (initial_index_count - 2) * 3;
|
||||
case Primitive_type::quads:
|
||||
case rsx::primitive_type::quads:
|
||||
return (6 * initial_index_count) / 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t get_index_type_size(Index_array_type type)
|
||||
size_t get_index_type_size(rsx::index_array_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Index_array_type::unsigned_16b: return 2;
|
||||
case Index_array_type::unsigned_32b: return 4;
|
||||
case rsx::index_array_type::u16: return sizeof(u16);
|
||||
case rsx::index_array_type::u32: return sizeof(u32);
|
||||
}
|
||||
throw new EXCEPTION("Wrong index type");
|
||||
}
|
||||
|
||||
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, Primitive_type draw_mode, unsigned first, unsigned count)
|
||||
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, rsx::primitive_type draw_mode, unsigned first, unsigned count)
|
||||
{
|
||||
unsigned short *typedDst = (unsigned short *)(dst);
|
||||
switch (draw_mode)
|
||||
{
|
||||
case Primitive_type::triangle_fan:
|
||||
case Primitive_type::polygon:
|
||||
case rsx::primitive_type::triangle_fan:
|
||||
case rsx::primitive_type::polygon:
|
||||
for (unsigned i = 0; i < (count - 2); i++)
|
||||
{
|
||||
typedDst[3 * i] = first;
|
||||
@@ -311,7 +308,7 @@ void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst,
|
||||
typedDst[3 * i + 2] = i + 2;
|
||||
}
|
||||
return;
|
||||
case Primitive_type::quads:
|
||||
case rsx::primitive_type::quads:
|
||||
for (unsigned i = 0; i < count / 4; i++)
|
||||
{
|
||||
// First triangle
|
||||
@@ -324,13 +321,13 @@ void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst,
|
||||
typedDst[6 * i + 5] = 4 * i + first;
|
||||
}
|
||||
return;
|
||||
case Primitive_type::points:
|
||||
case Primitive_type::lines:
|
||||
case Primitive_type::line_loop:
|
||||
case Primitive_type::line_strip:
|
||||
case Primitive_type::triangles:
|
||||
case Primitive_type::triangle_strip:
|
||||
case Primitive_type::quad_strip:
|
||||
case rsx::primitive_type::points:
|
||||
case rsx::primitive_type::lines:
|
||||
case rsx::primitive_type::line_loop:
|
||||
case rsx::primitive_type::line_strip:
|
||||
case rsx::primitive_type::triangles:
|
||||
case rsx::primitive_type::triangle_strip:
|
||||
case rsx::primitive_type::quad_strip:
|
||||
throw new EXCEPTION("Native primitive type doesn't require expansion");
|
||||
}
|
||||
}
|
||||
@@ -338,14 +335,14 @@ void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst,
|
||||
// TODO: Unify indexed and non indexed primitive expansion ?
|
||||
|
||||
template<typename T>
|
||||
std::tuple<T, T> write_index_array_data_to_buffer_impl(gsl::span<T, gsl::dynamic_range> dst, Primitive_type m_draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments)
|
||||
std::tuple<T, T> write_index_array_data_to_buffer_impl(gsl::span<T, gsl::dynamic_range> dst, rsx::primitive_type draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments)
|
||||
{
|
||||
u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf);
|
||||
Index_array_type type = to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
rsx::index_array_type type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
|
||||
u32 type_size = gsl::narrow<u32>(get_index_type_size(type));
|
||||
|
||||
Expects(rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET] == 0);
|
||||
|
||||
Expects(rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX] == 0);
|
||||
|
||||
bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE];
|
||||
@@ -362,40 +359,40 @@ std::tuple<T, T> write_index_array_data_to_buffer_impl(gsl::span<T, gsl::dynamic
|
||||
u32 count = std::get<0>(first_count_arguments.back()) + std::get<1>(first_count_arguments.back()) - first;
|
||||
auto ptr = vm::ps3::_ptr<const T>(address + first * type_size);
|
||||
|
||||
switch (m_draw_mode)
|
||||
switch (draw_mode)
|
||||
{
|
||||
case Primitive_type::points:
|
||||
case Primitive_type::lines:
|
||||
case Primitive_type::line_loop:
|
||||
case Primitive_type::line_strip:
|
||||
case Primitive_type::triangles:
|
||||
case Primitive_type::triangle_strip:
|
||||
case Primitive_type::quad_strip:
|
||||
case rsx::primitive_type::points:
|
||||
case rsx::primitive_type::lines:
|
||||
case rsx::primitive_type::line_loop:
|
||||
case rsx::primitive_type::line_strip:
|
||||
case rsx::primitive_type::triangles:
|
||||
case rsx::primitive_type::triangle_strip:
|
||||
case rsx::primitive_type::quad_strip:
|
||||
return upload_untouched<T>({ ptr, count }, dst, is_primitive_restart_enabled, primitive_restart_index);
|
||||
case Primitive_type::polygon:
|
||||
case Primitive_type::triangle_fan:
|
||||
case rsx::primitive_type::polygon:
|
||||
case rsx::primitive_type::triangle_fan:
|
||||
return expand_indexed_triangle_fan<T>({ ptr, count }, dst, is_primitive_restart_enabled, primitive_restart_index);
|
||||
case Primitive_type::quads:
|
||||
case rsx::primitive_type::quads:
|
||||
return expand_indexed_quads<T>({ ptr, count }, dst, is_primitive_restart_enabled, primitive_restart_index);
|
||||
}
|
||||
|
||||
throw new EXCEPTION("Unknow draw mode");
|
||||
}
|
||||
|
||||
std::tuple<u32, u32> write_index_array_data_to_buffer(gsl::span<u32, gsl::dynamic_range> dst, Primitive_type m_draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments)
|
||||
std::tuple<u32, u32> write_index_array_data_to_buffer(gsl::span<u32, gsl::dynamic_range> dst, rsx::primitive_type draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments)
|
||||
{
|
||||
return write_index_array_data_to_buffer_impl(dst, m_draw_mode, first_count_arguments);
|
||||
return write_index_array_data_to_buffer_impl(dst, draw_mode, first_count_arguments);
|
||||
}
|
||||
|
||||
std::tuple<u16, u16> write_index_array_data_to_buffer(gsl::span<u16, gsl::dynamic_range> dst, Primitive_type m_draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments)
|
||||
std::tuple<u16, u16> write_index_array_data_to_buffer(gsl::span<u16, gsl::dynamic_range> dst, rsx::primitive_type draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments)
|
||||
{
|
||||
return write_index_array_data_to_buffer_impl(dst, m_draw_mode, first_count_arguments);
|
||||
return write_index_array_data_to_buffer_impl(dst, draw_mode, first_count_arguments);
|
||||
}
|
||||
|
||||
std::tuple<u32, u32> write_index_array_data_to_buffer_untouched(gsl::span<u32, gsl::dynamic_range> dst, const std::vector<std::pair<u32, u32> > &first_count_arguments)
|
||||
{
|
||||
u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf);
|
||||
Index_array_type type = to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
rsx::index_array_type type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
|
||||
u32 type_size = gsl::narrow<u32>(get_index_type_size(type));
|
||||
bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE];
|
||||
@@ -418,7 +415,7 @@ std::tuple<u32, u32> write_index_array_data_to_buffer_untouched(gsl::span<u32, g
|
||||
std::tuple<u16, u16> write_index_array_data_to_buffer_untouched(gsl::span<u16, gsl::dynamic_range> dst, const std::vector<std::pair<u32, u32> > &first_count_arguments)
|
||||
{
|
||||
u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf);
|
||||
Index_array_type type = to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
rsx::index_array_type type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
|
||||
u32 type_size = gsl::narrow<u32>(get_index_type_size(type));
|
||||
bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE];
|
||||
|
||||
@@ -11,25 +11,25 @@ void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_
|
||||
/*
|
||||
* If primitive mode is not supported and need to be emulated (using an index buffer) returns false.
|
||||
*/
|
||||
bool is_primitive_native(Primitive_type m_draw_mode);
|
||||
bool is_primitive_native(rsx::primitive_type m_draw_mode);
|
||||
|
||||
/**
|
||||
* Returns a fixed index count for emulated primitive, otherwise returns initial_index_count
|
||||
*/
|
||||
size_t get_index_count(Primitive_type m_draw_mode, unsigned initial_index_count);
|
||||
size_t get_index_count(rsx::primitive_type m_draw_mode, unsigned initial_index_count);
|
||||
|
||||
/**
|
||||
* Returns index type size in byte
|
||||
*/
|
||||
size_t get_index_type_size(Index_array_type type);
|
||||
size_t get_index_type_size(rsx::index_array_type type);
|
||||
|
||||
/**
|
||||
* Write count indexes using (first, first + count) ranges.
|
||||
* Returns min/max index found during the process.
|
||||
* The function expands index buffer for non native primitive type.
|
||||
*/
|
||||
std::tuple<u32, u32> write_index_array_data_to_buffer(gsl::span<u32, gsl::dynamic_range> dst, Primitive_type m_draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments);
|
||||
std::tuple<u16, u16> write_index_array_data_to_buffer(gsl::span<u16, gsl::dynamic_range> dst, Primitive_type m_draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments);
|
||||
std::tuple<u32, u32> write_index_array_data_to_buffer(gsl::span<u32, gsl::dynamic_range> dst, rsx::primitive_type draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments);
|
||||
std::tuple<u16, u16> write_index_array_data_to_buffer(gsl::span<u16, gsl::dynamic_range> dst, rsx::primitive_type draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments);
|
||||
|
||||
/**
|
||||
* Doesn't expand index
|
||||
@@ -40,7 +40,7 @@ std::tuple<u16, u16> write_index_array_data_to_buffer_untouched(gsl::span<u16, g
|
||||
/**
|
||||
* Write index data needed to emulate non indexed non native primitive mode.
|
||||
*/
|
||||
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, Primitive_type m_draw_mode, unsigned first, unsigned count);
|
||||
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, rsx::primitive_type draw_mode, unsigned first, unsigned count);
|
||||
|
||||
/**
|
||||
* Stream a 128 bits vector to dst.
|
||||
|
||||
@@ -5,12 +5,11 @@
|
||||
#include "FragmentProgramDecompiler.h"
|
||||
|
||||
FragmentProgramDecompiler::FragmentProgramDecompiler(const RSXFragmentProgram &prog, u32& size) :
|
||||
m_addr(prog.addr),
|
||||
m_prog(prog),
|
||||
m_size(size),
|
||||
m_const_index(0),
|
||||
m_location(0),
|
||||
m_ctrl(prog.ctrl),
|
||||
m_texture_dimensions(prog.texture_dimensions)
|
||||
m_ctrl(prog.ctrl)
|
||||
{
|
||||
m_size = 0;
|
||||
}
|
||||
@@ -114,7 +113,7 @@ std::string FragmentProgramDecompiler::AddConst()
|
||||
return name;
|
||||
}
|
||||
|
||||
auto data = vm::ps3::ptr<u32>::make(m_addr + m_size + 4 * SIZE_32(u32));
|
||||
auto data = (be_t<u32>*) ((char*)m_prog.addr + m_size + 4 * SIZE_32(u32));
|
||||
|
||||
m_offset = 2 * 4 * sizeof(u32);
|
||||
u32 x = GetData(data[0]);
|
||||
@@ -128,7 +127,23 @@ std::string FragmentProgramDecompiler::AddConst()
|
||||
|
||||
std::string FragmentProgramDecompiler::AddTex()
|
||||
{
|
||||
return m_parr.AddParam(PF_PARAM_UNIFORM, (m_texture_dimensions[dst.tex_num] == texture_dimension::texture_dimension_cubemap) ? "samplerCube" : "sampler2D", std::string("tex") + std::to_string(dst.tex_num));
|
||||
std::string sampler;
|
||||
switch (m_prog.get_texture_dimension(dst.tex_num))
|
||||
{
|
||||
case texture_dimension::texture_dimension_1d:
|
||||
sampler = "sampler1D";
|
||||
break;
|
||||
case texture_dimension::texture_dimension_cubemap:
|
||||
sampler = "samplerCube";
|
||||
break;
|
||||
case texture_dimension::texture_dimension_2d:
|
||||
sampler = "sampler2D";
|
||||
break;
|
||||
case texture_dimension::texture_dimension_3d:
|
||||
sampler = "sampler3D";
|
||||
break;
|
||||
}
|
||||
return m_parr.AddParam(PF_PARAM_UNIFORM, sampler, std::string("tex") + std::to_string(dst.tex_num));
|
||||
}
|
||||
|
||||
std::string FragmentProgramDecompiler::Format(const std::string& code)
|
||||
@@ -259,7 +274,7 @@ template<typename T> std::string FragmentProgramDecompiler::GetSRC(T src)
|
||||
{
|
||||
static const std::string reg_table[] =
|
||||
{
|
||||
"gl_Position",
|
||||
"gl_FragCoord",
|
||||
"diff_color", "spec_color",
|
||||
"fogc",
|
||||
"tc0", "tc1", "tc2", "tc3", "tc4", "tc5", "tc6", "tc7", "tc8", "tc9",
|
||||
@@ -389,7 +404,7 @@ bool FragmentProgramDecompiler::handle_scb(u32 opcode)
|
||||
case RSX_FP_OPCODE_EX2: SetDst("exp2($0.xxxx)"); return true;
|
||||
case RSX_FP_OPCODE_FLR: SetDst("floor($0)"); return true;
|
||||
case RSX_FP_OPCODE_FRC: SetDst(getFunction(FUNCTION::FUNCTION_FRACT)); return true;
|
||||
case RSX_FP_OPCODE_LIT: SetDst(getFloatTypeName(4) + "(1.0, $0.x, ($0.x > 0.0 ? exp($0.w * log2($0.y)) : 0.0), 1.0)"); return true;
|
||||
case RSX_FP_OPCODE_LIT: SetDst("lit_legacy($0)"); return true;
|
||||
case RSX_FP_OPCODE_LIF: SetDst(getFloatTypeName(4) + "(1.0, $0.y, ($0.y > 0 ? pow(2.0, $0.w) : 0.0), 1.0)"); return true;
|
||||
case RSX_FP_OPCODE_LRP: LOG_ERROR(RSX, "Unimplemented SCB instruction: LRP"); return true; // TODO: Is this in the right category?
|
||||
case RSX_FP_OPCODE_LG2: SetDst("log2($0.xxxx)"); return true;
|
||||
@@ -425,35 +440,37 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
|
||||
case RSX_FP_OPCODE_NRM: SetDst("normalize($0)"); return true;
|
||||
case RSX_FP_OPCODE_BEM: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: BEM"); return true;
|
||||
case RSX_FP_OPCODE_TEX:
|
||||
if (dst.tex_num >= m_texture_dimensions.size())
|
||||
switch (m_prog.get_texture_dimension(dst.tex_num))
|
||||
{
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE));
|
||||
case texture_dimension::texture_dimension_1d:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D));
|
||||
return true;
|
||||
}
|
||||
switch (m_texture_dimensions[dst.tex_num])
|
||||
{
|
||||
case texture_dimension::texture_dimension_2d:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE));
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D));
|
||||
return true;
|
||||
case texture_dimension::texture_dimension_cubemap:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE));
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE));
|
||||
return true;
|
||||
case texture_dimension::texture_dimension_3d:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case RSX_FP_OPCODE_TEXBEM: SetDst("texture($t, $0.xy, $1.x)"); return true;
|
||||
case RSX_FP_OPCODE_TXP:
|
||||
if (dst.tex_num >= m_texture_dimensions.size())
|
||||
switch (m_prog.get_texture_dimension(dst.tex_num))
|
||||
{
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ));
|
||||
case texture_dimension::texture_dimension_1d:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ));
|
||||
return true;
|
||||
}
|
||||
switch (m_texture_dimensions[dst.tex_num])
|
||||
{
|
||||
case texture_dimension::texture_dimension_2d:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ));
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ));
|
||||
return true;
|
||||
case texture_dimension::texture_dimension_cubemap:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ));
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ));
|
||||
return true;
|
||||
case texture_dimension::texture_dimension_3d:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -461,18 +478,19 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
|
||||
case RSX_FP_OPCODE_TXD: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: TXD"); return true;
|
||||
case RSX_FP_OPCODE_TXB: SetDst("texture($t, $0.xy, $1.x)"); return true;
|
||||
case RSX_FP_OPCODE_TXL:
|
||||
if (dst.tex_num >= m_texture_dimensions.size())
|
||||
switch (m_prog.get_texture_dimension(dst.tex_num))
|
||||
{
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE_LOD));
|
||||
case texture_dimension::texture_dimension_1d:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD));
|
||||
return true;
|
||||
}
|
||||
switch (m_texture_dimensions[dst.tex_num])
|
||||
{
|
||||
case texture_dimension::texture_dimension_2d:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE_LOD));
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD));
|
||||
return true;
|
||||
case texture_dimension::texture_dimension_cubemap:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_LOD));
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD));
|
||||
return true;
|
||||
case texture_dimension::texture_dimension_3d:
|
||||
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -487,7 +505,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
|
||||
|
||||
std::string FragmentProgramDecompiler::Decompile()
|
||||
{
|
||||
auto data = vm::ps3::ptr<u32>::make(m_addr);
|
||||
auto data = (be_t<u32>*) m_prog.addr;
|
||||
m_size = 0;
|
||||
m_location = 0;
|
||||
m_loop_count = 0;
|
||||
|
||||
@@ -25,9 +25,7 @@ class FragmentProgramDecompiler
|
||||
SRC2 src2;
|
||||
|
||||
std::string main;
|
||||
u32 m_addr;
|
||||
u32& m_size;
|
||||
const std::vector<texture_dimension> m_texture_dimensions;
|
||||
u32 m_const_index;
|
||||
u32 m_offset;
|
||||
u32 m_location;
|
||||
@@ -76,6 +74,7 @@ class FragmentProgramDecompiler
|
||||
*/
|
||||
bool handle_tex_srb(u32 opcode);
|
||||
protected:
|
||||
const RSXFragmentProgram &m_prog;
|
||||
u32 m_ctrl;
|
||||
/** returns the type name of float vectors.
|
||||
*/
|
||||
|
||||
@@ -74,11 +74,11 @@ size_t fragment_program_utils::get_fragment_program_ucode_size(void *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
size_t fragment_program_hash::operator()(const void *program) const
|
||||
size_t fragment_program_hash::operator()(const RSXFragmentProgram& program) const
|
||||
{
|
||||
// 64-bit Fowler/Noll/Vo FNV-1a hash code
|
||||
size_t hash = 0xCBF29CE484222325ULL;
|
||||
const qword *instbuffer = (const qword*)program;
|
||||
const qword *instbuffer = (const qword*)program.addr;
|
||||
size_t instIndex = 0;
|
||||
while (true)
|
||||
{
|
||||
@@ -101,10 +101,15 @@ size_t fragment_program_hash::operator()(const void *program) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool fragment_program_compare::operator()(const void *binary1, const void *binary2) const
|
||||
bool fragment_program_compare::operator()(const RSXFragmentProgram& binary1, const RSXFragmentProgram& binary2) const
|
||||
{
|
||||
const qword *instBuffer1 = (const qword*)binary1;
|
||||
const qword *instBuffer2 = (const qword*)binary2;
|
||||
if (binary1.texture_dimensions != binary2.texture_dimensions || binary1.unnormalized_coords != binary2.unnormalized_coords ||
|
||||
binary1.height != binary2.height || binary1.origin_mode != binary2.origin_mode || binary1.pixel_center_mode != binary2.pixel_center_mode ||
|
||||
binary1.back_color_diffuse_output != binary2.back_color_diffuse_output || binary1.back_color_specular_output != binary2.back_color_specular_output ||
|
||||
binary1.front_back_color_enabled != binary2.front_back_color_enabled || binary1.alpha_func != binary2.alpha_func)
|
||||
return false;
|
||||
const qword *instBuffer1 = (const qword*)binary1.addr;
|
||||
const qword *instBuffer2 = (const qword*)binary2.addr;
|
||||
size_t instIndex = 0;
|
||||
while (true)
|
||||
{
|
||||
|
||||
@@ -43,12 +43,12 @@ namespace program_hash_util
|
||||
|
||||
struct fragment_program_hash
|
||||
{
|
||||
size_t operator()(const void *program) const;
|
||||
size_t operator()(const RSXFragmentProgram &program) const;
|
||||
};
|
||||
|
||||
struct fragment_program_compare
|
||||
{
|
||||
bool operator()(const void *binary1, const void *binary2) const;
|
||||
bool operator()(const RSXFragmentProgram &binary1, const RSXFragmentProgram &binary2) const;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ class program_state_cache
|
||||
using fragment_program_type = typename backend_traits::fragment_program_type;
|
||||
|
||||
using binary_to_vertex_program = std::unordered_map<RSXVertexProgram, vertex_program_type, program_hash_util::vertex_program_hash, program_hash_util::vertex_program_compare> ;
|
||||
using binary_to_fragment_program = std::unordered_map<void *, fragment_program_type, program_hash_util::fragment_program_hash, program_hash_util::fragment_program_compare>;
|
||||
using binary_to_fragment_program = std::unordered_map<RSXFragmentProgram, fragment_program_type, program_hash_util::fragment_program_hash, program_hash_util::fragment_program_compare>;
|
||||
|
||||
|
||||
struct pipeline_key
|
||||
@@ -130,16 +130,18 @@ private:
|
||||
/// bool here to inform that the program was preexisting.
|
||||
std::tuple<const fragment_program_type&, bool> search_fragment_program(const RSXFragmentProgram& rsx_fp)
|
||||
{
|
||||
const auto& I = m_fragment_shader_cache.find(vm::base(rsx_fp.addr));
|
||||
const auto& I = m_fragment_shader_cache.find(rsx_fp);
|
||||
if (I != m_fragment_shader_cache.end())
|
||||
{
|
||||
return std::forward_as_tuple(I->second, true);
|
||||
}
|
||||
LOG_NOTICE(RSX, "FP not found in buffer!");
|
||||
size_t fragment_program_size = program_hash_util::fragment_program_utils::get_fragment_program_ucode_size(vm::base(rsx_fp.addr));
|
||||
size_t fragment_program_size = program_hash_util::fragment_program_utils::get_fragment_program_ucode_size(rsx_fp.addr);
|
||||
gsl::not_null<void*> fragment_program_ucode_copy = malloc(fragment_program_size);
|
||||
std::memcpy(fragment_program_ucode_copy, vm::base(rsx_fp.addr), fragment_program_size);
|
||||
fragment_program_type &new_shader = m_fragment_shader_cache[fragment_program_ucode_copy];
|
||||
std::memcpy(fragment_program_ucode_copy, rsx_fp.addr, fragment_program_size);
|
||||
RSXFragmentProgram new_fp_key = rsx_fp;
|
||||
new_fp_key.addr = fragment_program_ucode_copy;
|
||||
fragment_program_type &new_shader = m_fragment_shader_cache[new_fp_key];
|
||||
backend_traits::recompile_fragment_program(rsx_fp, new_shader, m_next_id++);
|
||||
|
||||
return std::forward_as_tuple(new_shader, false);
|
||||
@@ -147,7 +149,13 @@ private:
|
||||
|
||||
public:
|
||||
program_state_cache() = default;
|
||||
~program_state_cache() = default;
|
||||
~program_state_cache()
|
||||
{
|
||||
for (auto& pair : m_fragment_shader_cache)
|
||||
{
|
||||
free(pair.first.addr);
|
||||
}
|
||||
};
|
||||
|
||||
const vertex_program_type& get_transform_program(const RSXVertexProgram& rsx_vp) const
|
||||
{
|
||||
@@ -159,7 +167,7 @@ public:
|
||||
|
||||
const fragment_program_type& get_shader_program(const RSXFragmentProgram& rsx_fp) const
|
||||
{
|
||||
auto I = m_fragment_shader_cache.find(vm::base(rsx_fp.addr));
|
||||
auto I = m_fragment_shader_cache.find(rsx_fp);
|
||||
if (I != m_fragment_shader_cache.end())
|
||||
return I->second;
|
||||
throw new EXCEPTION("Trying to get unknow shader program");
|
||||
@@ -200,7 +208,7 @@ public:
|
||||
|
||||
size_t get_fragment_constants_buffer_size(const RSXFragmentProgram &fragmentShader) const
|
||||
{
|
||||
const auto I = m_fragment_shader_cache.find(vm::base(fragmentShader.addr));
|
||||
const auto I = m_fragment_shader_cache.find(fragmentShader);
|
||||
if (I != m_fragment_shader_cache.end())
|
||||
return I->second.FragmentConstantOffsetCache.size() * 4 * sizeof(float);
|
||||
LOG_ERROR(RSX, "Can't retrieve constant offset cache");
|
||||
@@ -209,7 +217,7 @@ public:
|
||||
|
||||
void fill_fragment_constans_buffer(gsl::span<f32, gsl::dynamic_range> dst_buffer, const RSXFragmentProgram &fragment_program) const
|
||||
{
|
||||
const auto I = m_fragment_shader_cache.find(vm::base(fragment_program.addr));
|
||||
const auto I = m_fragment_shader_cache.find(fragment_program);
|
||||
if (I == m_fragment_shader_cache.end())
|
||||
return;
|
||||
__m128i mask = _mm_set_epi8(0xE, 0xF, 0xC, 0xD,
|
||||
@@ -222,11 +230,16 @@ public:
|
||||
size_t offset = 0;
|
||||
for (size_t offset_in_fragment_program : I->second.FragmentConstantOffsetCache)
|
||||
{
|
||||
void *data = vm::base(fragment_program.addr + (u32)offset_in_fragment_program);
|
||||
void *data = (char*)fragment_program.addr + (u32)offset_in_fragment_program;
|
||||
const __m128i &vector = _mm_loadu_si128((__m128i*)data);
|
||||
const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask);
|
||||
_mm_stream_si128((__m128i*)dst_buffer.subspan(offset, 4).data(), shuffled_vector);
|
||||
offset += sizeof(f32);
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_storage.clear();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,12 +13,18 @@ enum class FUNCTION {
|
||||
FUNCTION_FRACT,
|
||||
FUNCTION_DFDX,
|
||||
FUNCTION_DFDY,
|
||||
FUNCTION_TEXTURE_SAMPLE,
|
||||
FUNCTION_TEXTURE_SAMPLE_PROJ,
|
||||
FUNCTION_TEXTURE_SAMPLE_LOD,
|
||||
FUNCTION_TEXTURE_CUBE_SAMPLE,
|
||||
FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ,
|
||||
FUNCTION_TEXTURE_CUBE_SAMPLE_LOD,
|
||||
FUNCTION_TEXTURE_SAMPLE1D,
|
||||
FUNCTION_TEXTURE_SAMPLE1D_PROJ,
|
||||
FUNCTION_TEXTURE_SAMPLE1D_LOD,
|
||||
FUNCTION_TEXTURE_SAMPLE2D,
|
||||
FUNCTION_TEXTURE_SAMPLE2D_PROJ,
|
||||
FUNCTION_TEXTURE_SAMPLE2D_LOD,
|
||||
FUNCTION_TEXTURE_SAMPLECUBE,
|
||||
FUNCTION_TEXTURE_SAMPLECUBE_PROJ,
|
||||
FUNCTION_TEXTURE_SAMPLECUBE_LOD,
|
||||
FUNCTION_TEXTURE_SAMPLE3D,
|
||||
FUNCTION_TEXTURE_SAMPLE3D_PROJ,
|
||||
FUNCTION_TEXTURE_SAMPLE3D_LOD,
|
||||
};
|
||||
|
||||
enum class COMPARE {
|
||||
|
||||
@@ -14,9 +14,9 @@ namespace
|
||||
struct texel_rgba
|
||||
{
|
||||
template<size_t block_size>
|
||||
static void copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block)
|
||||
static void copy_mipmap_level(void *dst, void *src, u16 row_count, u16 width_in_block, u16 depth, size_t dst_pitch_in_block, size_t src_pitch_in_block)
|
||||
{
|
||||
for (unsigned row = 0; row < row_count; row++)
|
||||
for (unsigned row = 0; row < row_count * depth; row++)
|
||||
memcpy((char*)dst + row * dst_pitch_in_block * block_size, (char*)src + row * src_pitch_in_block * block_size, width_in_block * block_size);
|
||||
}
|
||||
};
|
||||
@@ -28,13 +28,13 @@ struct texel_rgba
|
||||
struct texel_16b_swizzled
|
||||
{
|
||||
template<size_t block_size>
|
||||
static void copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block)
|
||||
static void copy_mipmap_level(void *dst, void *src, u16 row_count, u16 width_in_block, u16 depth, size_t dst_pitch_in_block, size_t src_pitch_in_block)
|
||||
{
|
||||
u16 *castedSrc = static_cast<u16*>(src), *castedDst = static_cast<u16*>(dst);
|
||||
|
||||
std::unique_ptr<u16[]> temp_swizzled(new u16[row_count * width_in_block]);
|
||||
rsx::convert_linear_swizzle<u16>(castedSrc, temp_swizzled.get(), src_pitch_in_block, row_count, true);
|
||||
for (unsigned row = 0; row < row_count; row++)
|
||||
for (unsigned row = 0; row < row_count * depth; row++)
|
||||
for (int j = 0; j < width_in_block; j++)
|
||||
{
|
||||
u16 tmp = temp_swizzled[row * src_pitch_in_block + j];
|
||||
@@ -49,14 +49,14 @@ struct texel_16b_swizzled
|
||||
struct texel_rgba_swizzled
|
||||
{
|
||||
template<size_t block_size>
|
||||
static void copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block)
|
||||
static void copy_mipmap_level(void *dst, void *src, u16 row_count, u16 width_in_block, u16 depth, size_t dst_pitch_in_block, size_t src_pitch_in_block)
|
||||
{
|
||||
u32 *castedSrc, *castedDst;
|
||||
castedSrc = (u32*)src;
|
||||
castedDst = (u32*)dst ;
|
||||
std::unique_ptr<u32[]> temp_swizzled(new u32[src_pitch_in_block * row_count]);
|
||||
rsx::convert_linear_swizzle<u32>(castedSrc, temp_swizzled.get(), src_pitch_in_block, row_count, true);
|
||||
for (unsigned row = 0; row < row_count; row++)
|
||||
for (unsigned row = 0; row < row_count * depth; row++)
|
||||
memcpy((char*)dst + row * dst_pitch_in_block * block_size, (char*)temp_swizzled.get() + row * src_pitch_in_block * block_size, width_in_block * block_size);
|
||||
}
|
||||
};
|
||||
@@ -67,9 +67,9 @@ struct texel_rgba_swizzled
|
||||
*/
|
||||
struct texel_bc_format {
|
||||
template<size_t block_size>
|
||||
static void copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block)
|
||||
static void copy_mipmap_level(void *dst, void *src, u16 row_count, u16 width_in_block, u16 depth, size_t dst_pitch_in_block, size_t src_pitch_in_block)
|
||||
{
|
||||
for (unsigned row = 0; row < row_count; row++)
|
||||
for (unsigned row = 0; row < row_count * depth; row++)
|
||||
memcpy((char*)dst + row * dst_pitch_in_block * block_size, (char*)src + row * src_pitch_in_block * block_size, width_in_block * block_size);
|
||||
}
|
||||
};
|
||||
@@ -79,11 +79,11 @@ struct texel_bc_format {
|
||||
*/
|
||||
struct texel_16b_format {
|
||||
template<size_t block_size>
|
||||
static void copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block)
|
||||
static void copy_mipmap_level(void *dst, void *src, u16 row_count, u16 width_in_block, u16 depth, size_t dst_pitch_in_block, size_t src_pitch_in_block)
|
||||
{
|
||||
unsigned short *castedDst = (unsigned short *)dst, *castedSrc = (unsigned short *)src;
|
||||
|
||||
for (unsigned row = 0; row < row_count; row++)
|
||||
for (unsigned row = 0; row < row_count * depth; row++)
|
||||
for (int j = 0; j < width_in_block; j++)
|
||||
{
|
||||
u16 tmp = castedSrc[row * src_pitch_in_block + j];
|
||||
@@ -97,10 +97,10 @@ struct texel_16b_format {
|
||||
*/
|
||||
struct texel_16bX4_format {
|
||||
template<size_t block_size>
|
||||
static void copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block)
|
||||
static void copy_mipmap_level(void *dst, void *src, u16 row_count, u16 width_in_block, u16 depth, size_t dst_pitch_in_block, size_t src_pitch_in_block)
|
||||
{
|
||||
unsigned short *casted_dst = (unsigned short *)dst, *casted_src = (unsigned short *)src;
|
||||
for (unsigned row = 0; row < row_count; row++)
|
||||
for (unsigned row = 0; row < row_count * depth; row++)
|
||||
for (int j = 0; j < width_in_block * 4; j++)
|
||||
{
|
||||
u16 tmp = casted_src[row * src_pitch_in_block * 4 + j];
|
||||
@@ -124,13 +124,13 @@ struct texel_16bX4_format {
|
||||
* mipmap level (to allow same code for packed/non packed texels)
|
||||
*/
|
||||
template <typename T, bool padded_row, size_t block_size_in_bytes, size_t block_edge_in_texel>
|
||||
std::vector<MipmapLevelInfo> copy_texture_data(void *dst, const void *src, size_t width_in_texel, size_t height_in_texel, size_t depth, size_t mipmap_count)
|
||||
std::vector<MipmapLevelInfo> copy_texture_data(void *dst, const void *src, u16 width_in_texel, u16 height_in_texel, u16 depth, u8 layer_count, u16 mipmap_count)
|
||||
{
|
||||
std::vector<MipmapLevelInfo> Result;
|
||||
size_t offsetInDst = 0, offsetInSrc = 0;
|
||||
size_t texture_height_in_block = (height_in_texel + block_edge_in_texel - 1) / block_edge_in_texel;
|
||||
size_t texture_width_in_block = (width_in_texel + block_edge_in_texel - 1) / block_edge_in_texel;
|
||||
for (unsigned depth_level = 0; depth_level < depth; depth_level++)
|
||||
for (unsigned layer = 0; layer < layer_count; layer++)
|
||||
{
|
||||
size_t miplevel_height_in_block = texture_height_in_block, miplevel_width_in_block = texture_width_in_block;
|
||||
for (unsigned mip_level = 0; mip_level < mipmap_count; mip_level++)
|
||||
@@ -141,18 +141,19 @@ std::vector<MipmapLevelInfo> copy_texture_data(void *dst, const void *src, size_
|
||||
currentMipmapLevelInfo.offset = offsetInDst;
|
||||
currentMipmapLevelInfo.height = miplevel_height_in_block * block_edge_in_texel;
|
||||
currentMipmapLevelInfo.width = miplevel_width_in_block * block_edge_in_texel;
|
||||
currentMipmapLevelInfo.depth = depth;
|
||||
currentMipmapLevelInfo.rowPitch = dst_pitch * block_size_in_bytes;
|
||||
Result.push_back(currentMipmapLevelInfo);
|
||||
|
||||
if (!padded_row)
|
||||
{
|
||||
T::template copy_mipmap_level<block_size_in_bytes>((char*)dst + offsetInDst, (char*)src + offsetInSrc, miplevel_height_in_block, miplevel_width_in_block, dst_pitch, miplevel_width_in_block);
|
||||
offsetInSrc += miplevel_height_in_block * miplevel_width_in_block * block_size_in_bytes;
|
||||
T::template copy_mipmap_level<block_size_in_bytes>((char*)dst + offsetInDst, (char*)src + offsetInSrc, miplevel_height_in_block, miplevel_width_in_block, depth, dst_pitch, miplevel_width_in_block);
|
||||
offsetInSrc += miplevel_height_in_block * miplevel_width_in_block * block_size_in_bytes * depth;
|
||||
}
|
||||
else
|
||||
{
|
||||
T::template copy_mipmap_level<block_size_in_bytes>((char*)dst + offsetInDst, (char*)src + offsetInSrc, miplevel_height_in_block, miplevel_width_in_block, dst_pitch, texture_width_in_block);
|
||||
offsetInSrc += miplevel_height_in_block * texture_width_in_block * block_size_in_bytes;
|
||||
T::template copy_mipmap_level<block_size_in_bytes>((char*)dst + offsetInDst, (char*)src + offsetInSrc, miplevel_height_in_block, miplevel_width_in_block, depth, dst_pitch, texture_width_in_block);
|
||||
offsetInSrc += miplevel_height_in_block * texture_width_in_block * block_size_in_bytes * depth;
|
||||
}
|
||||
offsetInDst += align(miplevel_height_in_block * dst_pitch * block_size_in_bytes, 512);
|
||||
miplevel_height_in_block = MAX2(miplevel_height_in_block / 2, 1);
|
||||
@@ -265,10 +266,28 @@ size_t get_placed_texture_storage_size(const rsx::texture &texture, size_t rowPi
|
||||
|
||||
std::vector<MipmapLevelInfo> upload_placed_texture(const rsx::texture &texture, size_t rowPitchAlignement, void* textureData)
|
||||
{
|
||||
size_t w = texture.width(), h = texture.height();
|
||||
size_t depth = texture.depth();
|
||||
if (depth == 0) depth = 1;
|
||||
if (texture.cubemap()) depth *= 6;
|
||||
u16 w = texture.width(), h = texture.height();
|
||||
u16 depth;
|
||||
u8 layer;
|
||||
|
||||
if (texture.dimension() == 1)
|
||||
{
|
||||
depth = 1;
|
||||
layer = 1;
|
||||
h = 1;
|
||||
}
|
||||
else if (texture.dimension() == 2)
|
||||
{
|
||||
depth = 1;
|
||||
layer = texture.cubemap() ? 6 : 1;
|
||||
}
|
||||
else if (texture.dimension() == 3)
|
||||
{
|
||||
depth = texture.depth();
|
||||
layer = 1;
|
||||
}
|
||||
else
|
||||
throw EXCEPTION("Unsupported texture dimension %d", texture.dimension());
|
||||
|
||||
int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
|
||||
@@ -281,37 +300,37 @@ std::vector<MipmapLevelInfo> upload_placed_texture(const rsx::texture &texture,
|
||||
{
|
||||
case CELL_GCM_TEXTURE_A8R8G8B8:
|
||||
if (is_swizzled)
|
||||
return copy_texture_data<texel_rgba_swizzled, false, 4, 1>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_rgba_swizzled, false, 4, 1>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
else
|
||||
return copy_texture_data<texel_rgba, true, 4, 1>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_rgba, true, 4, 1>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
case CELL_GCM_TEXTURE_A1R5G5B5:
|
||||
case CELL_GCM_TEXTURE_A4R4G4B4:
|
||||
case CELL_GCM_TEXTURE_R5G6B5:
|
||||
if (is_swizzled)
|
||||
return copy_texture_data<texel_16b_swizzled, false, 2, 1>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_16b_swizzled, false, 2, 1>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
else
|
||||
return copy_texture_data<texel_16b_format, true, 2, 1>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_16b_format, true, 2, 1>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
|
||||
return copy_texture_data<texel_16bX4_format, true, 8, 1>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_16bX4_format, true, 8, 1>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_DXT1:
|
||||
if (is_swizzled)
|
||||
return copy_texture_data<texel_bc_format, false, 8, 4>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_bc_format, false, 8, 4>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
else
|
||||
return copy_texture_data<texel_bc_format, true, 8, 4>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_bc_format, true, 8, 4>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_DXT23:
|
||||
if (is_swizzled)
|
||||
return copy_texture_data<texel_bc_format, false, 16, 4>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_bc_format, false, 16, 4>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
else
|
||||
return copy_texture_data<texel_bc_format, true, 16, 4>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_bc_format, true, 16, 4>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_DXT45:
|
||||
if (is_swizzled)
|
||||
return copy_texture_data<texel_bc_format, false, 16, 4>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_bc_format, false, 16, 4>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
else
|
||||
return copy_texture_data<texel_bc_format, true, 16, 4>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_bc_format, true, 16, 4>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
case CELL_GCM_TEXTURE_B8:
|
||||
return copy_texture_data<texel_rgba, true, 1, 1>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_rgba, true, 1, 1>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
default:
|
||||
return copy_texture_data<texel_rgba, true, 4, 1>(textureData, pixels, w, h, depth, texture.mipmap());
|
||||
return copy_texture_data<texel_rgba, true, 4, 1>(textureData, pixels, w, h, depth, layer, texture.mipmap());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
struct MipmapLevelInfo
|
||||
{
|
||||
size_t offset;
|
||||
size_t width;
|
||||
size_t height;
|
||||
size_t rowPitch;
|
||||
u16 width;
|
||||
u16 height;
|
||||
u16 depth;
|
||||
u16 rowPitch;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -562,10 +562,10 @@ std::string VertexProgramDecompiler::Decompile()
|
||||
case RSX_SCA_OPCODE_MOV: SetDSTSca("$s"); break;
|
||||
case RSX_SCA_OPCODE_RCP: SetDSTSca("(1.0 / $s)"); break;
|
||||
case RSX_SCA_OPCODE_RCC: SetDSTSca("clamp(1.0 / $s, 5.42101e-20, 1.884467e19)"); break;
|
||||
case RSX_SCA_OPCODE_RSQ: SetDSTSca("(1.f / sqrt($s))"); break;
|
||||
case RSX_SCA_OPCODE_RSQ: SetDSTSca("rsq_legacy($s)"); break;
|
||||
case RSX_SCA_OPCODE_EXP: SetDSTSca("exp($s)"); break;
|
||||
case RSX_SCA_OPCODE_LOG: SetDSTSca("log($s)"); break;
|
||||
case RSX_SCA_OPCODE_LIT: SetDSTSca(getFloatTypeName(4) + "(1.0, $s.x, ($s.x > 0.0 ? exp($s.w * log2($s.y)) : 0.0), 1.0)"); break;
|
||||
case RSX_SCA_OPCODE_LIT: SetDSTSca("lit_legacy($s)"); break;
|
||||
case RSX_SCA_OPCODE_BRA:
|
||||
{
|
||||
AddCode("$if ($cond)");
|
||||
@@ -619,7 +619,7 @@ std::string VertexProgramDecompiler::Decompile()
|
||||
// works like BRI but shorter (RET o[1].x(TR);)
|
||||
AddCode("$ifcond return;");
|
||||
break;
|
||||
case RSX_SCA_OPCODE_LG2: SetDSTSca("log2($s)"); break;
|
||||
case RSX_SCA_OPCODE_LG2: SetDSTSca("log2_legacy($s)"); break;
|
||||
case RSX_SCA_OPCODE_EX2: SetDSTSca("exp2($s)"); break;
|
||||
case RSX_SCA_OPCODE_SIN: SetDSTSca("sin($s)"); break;
|
||||
case RSX_SCA_OPCODE_COS: SetDSTSca("cos($s)"); break;
|
||||
|
||||
@@ -5,60 +5,60 @@ namespace rsx
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
std::vector<u8> get_rtt_indexes(Surface_target color_target)
|
||||
std::vector<u8> get_rtt_indexes(surface_target color_target)
|
||||
{
|
||||
switch (color_target)
|
||||
{
|
||||
case Surface_target::none: return{};
|
||||
case Surface_target::surface_a: return{ 0 };
|
||||
case Surface_target::surface_b: return{ 1 };
|
||||
case Surface_target::surfaces_a_b: return{ 0, 1 };
|
||||
case Surface_target::surfaces_a_b_c: return{ 0, 1, 2 };
|
||||
case Surface_target::surfaces_a_b_c_d: return{ 0, 1, 2, 3 };
|
||||
case surface_target::none: return{};
|
||||
case surface_target::surface_a: return{ 0 };
|
||||
case surface_target::surface_b: return{ 1 };
|
||||
case surface_target::surfaces_a_b: return{ 0, 1 };
|
||||
case surface_target::surfaces_a_b_c: return{ 0, 1, 2 };
|
||||
case surface_target::surfaces_a_b_c_d: return{ 0, 1, 2, 3 };
|
||||
}
|
||||
throw EXCEPTION("Wrong color_target");
|
||||
}
|
||||
|
||||
size_t get_aligned_pitch(Surface_color_format format, u32 width)
|
||||
size_t get_aligned_pitch(surface_color_format format, u32 width)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Surface_color_format::b8: return align(width, 256);
|
||||
case Surface_color_format::g8b8:
|
||||
case Surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case Surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
case Surface_color_format::r5g6b5: return align(width * 2, 256);
|
||||
case Surface_color_format::a8b8g8r8:
|
||||
case Surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case Surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case Surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case Surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case Surface_color_format::x32:
|
||||
case Surface_color_format::a8r8g8b8: return align(width * 4, 256);
|
||||
case Surface_color_format::w16z16y16x16: return align(width * 8, 256);
|
||||
case Surface_color_format::w32z32y32x32: return align(width * 16, 256);
|
||||
case surface_color_format::b8: return align(width, 256);
|
||||
case surface_color_format::g8b8:
|
||||
case surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
case surface_color_format::r5g6b5: return align(width * 2, 256);
|
||||
case surface_color_format::a8b8g8r8:
|
||||
case surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case surface_color_format::x32:
|
||||
case surface_color_format::a8r8g8b8: return align(width * 4, 256);
|
||||
case surface_color_format::w16z16y16x16: return align(width * 8, 256);
|
||||
case surface_color_format::w32z32y32x32: return align(width * 16, 256);
|
||||
}
|
||||
throw EXCEPTION("Unknow color surface format");
|
||||
}
|
||||
|
||||
size_t get_packed_pitch(Surface_color_format format, u32 width)
|
||||
size_t get_packed_pitch(surface_color_format format, u32 width)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Surface_color_format::b8: return width;
|
||||
case Surface_color_format::g8b8:
|
||||
case Surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case Surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
case Surface_color_format::r5g6b5: return width * 2;
|
||||
case Surface_color_format::a8b8g8r8:
|
||||
case Surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case Surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case Surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case Surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case Surface_color_format::x32:
|
||||
case Surface_color_format::a8r8g8b8: return width * 4;
|
||||
case Surface_color_format::w16z16y16x16: return width * 8;
|
||||
case Surface_color_format::w32z32y32x32: return width * 16;
|
||||
case surface_color_format::b8: return width;
|
||||
case surface_color_format::g8b8:
|
||||
case surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
case surface_color_format::r5g6b5: return width * 2;
|
||||
case surface_color_format::a8b8g8r8:
|
||||
case surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case surface_color_format::x32:
|
||||
case surface_color_format::a8r8g8b8: return width * 4;
|
||||
case surface_color_format::w16z16y16x16: return width * 8;
|
||||
case surface_color_format::w32z32y32x32: return width * 16;
|
||||
}
|
||||
throw EXCEPTION("Unknow color surface format");
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@ namespace rsx
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
std::vector<u8> get_rtt_indexes(Surface_target color_target);
|
||||
size_t get_aligned_pitch(Surface_color_format format, u32 width);
|
||||
size_t get_packed_pitch(Surface_color_format format, u32 width);
|
||||
std::vector<u8> get_rtt_indexes(surface_target color_target);
|
||||
size_t get_aligned_pitch(surface_color_format format, u32 width);
|
||||
size_t get_packed_pitch(surface_color_format format, u32 width);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,7 +86,7 @@ namespace rsx
|
||||
gsl::not_null<surface_type> bind_address_as_render_targets(
|
||||
command_list_type command_list,
|
||||
u32 address,
|
||||
Surface_color_format surface_color_format, size_t width, size_t height,
|
||||
surface_color_format color_format, size_t width, size_t height,
|
||||
Args&&... extra_params)
|
||||
{
|
||||
auto It = m_render_targets_storage.find(address);
|
||||
@@ -96,7 +96,7 @@ namespace rsx
|
||||
if (It != m_render_targets_storage.end())
|
||||
{
|
||||
surface_storage_type &rtt = It->second;
|
||||
if (Traits::rtt_has_format_width_height(rtt, surface_color_format, width, height))
|
||||
if (Traits::rtt_has_format_width_height(rtt, color_format, width, height))
|
||||
{
|
||||
Traits::prepare_rtt_for_drawing(command_list, Traits::get(rtt));
|
||||
return Traits::get(rtt);
|
||||
@@ -105,7 +105,7 @@ namespace rsx
|
||||
m_render_targets_storage.erase(address);
|
||||
}
|
||||
|
||||
m_render_targets_storage[address] = Traits::create_new_surface(address, surface_color_format, width, height, std::forward<Args>(extra_params)...);
|
||||
m_render_targets_storage[address] = Traits::create_new_surface(address, color_format, width, height, std::forward<Args>(extra_params)...);
|
||||
return Traits::get(m_render_targets_storage[address]);
|
||||
}
|
||||
|
||||
@@ -113,14 +113,14 @@ namespace rsx
|
||||
gsl::not_null<surface_type> bind_address_as_depth_stencil(
|
||||
command_list_type command_list,
|
||||
u32 address,
|
||||
Surface_depth_format surface_depth_format, size_t width, size_t height,
|
||||
surface_depth_format depth_format, size_t width, size_t height,
|
||||
Args&&... extra_params)
|
||||
{
|
||||
auto It = m_depth_stencil_storage.find(address);
|
||||
if (It != m_depth_stencil_storage.end())
|
||||
{
|
||||
surface_storage_type &ds = It->second;
|
||||
if (Traits::ds_has_format_width_height(ds, surface_depth_format, width, height))
|
||||
if (Traits::ds_has_format_width_height(ds, depth_format, width, height))
|
||||
{
|
||||
Traits::prepare_ds_for_drawing(command_list, Traits::get(ds));
|
||||
return Traits::get(ds);
|
||||
@@ -129,7 +129,7 @@ namespace rsx
|
||||
m_depth_stencil_storage.erase(address);
|
||||
}
|
||||
|
||||
m_depth_stencil_storage[address] = Traits::create_new_surface(address, surface_depth_format, width, height, std::forward<Args>(extra_params)...);
|
||||
m_depth_stencil_storage[address] = Traits::create_new_surface(address, depth_format, width, height, std::forward<Args>(extra_params)...);
|
||||
return Traits::get(m_depth_stencil_storage[address]);
|
||||
}
|
||||
public:
|
||||
@@ -142,7 +142,7 @@ namespace rsx
|
||||
command_list_type command_list,
|
||||
u32 set_surface_format_reg,
|
||||
u32 clip_horizontal_reg, u32 clip_vertical_reg,
|
||||
Surface_target set_surface_target,
|
||||
surface_target set_surface_target,
|
||||
const std::array<u32, 4> &surface_addresses, u32 address_z,
|
||||
Args&&... extra_params)
|
||||
{
|
||||
@@ -151,8 +151,8 @@ namespace rsx
|
||||
u32 clip_x = clip_horizontal_reg;
|
||||
u32 clip_y = clip_vertical_reg;
|
||||
|
||||
Surface_color_format color_format = to_surface_color_format(set_surface_format_reg & 0x1f);
|
||||
Surface_depth_format depth_format = to_surface_depth_format((set_surface_format_reg >> 5) & 0x7);
|
||||
surface_color_format color_format = to_surface_color_format(set_surface_format_reg & 0x1f);
|
||||
surface_depth_format depth_format = to_surface_depth_format((set_surface_format_reg >> 5) & 0x7);
|
||||
|
||||
// Make previous RTTs sampleable
|
||||
for (std::tuple<u32, surface_type> &rtt : m_bound_render_targets)
|
||||
@@ -216,7 +216,7 @@ namespace rsx
|
||||
*/
|
||||
template <typename... Args>
|
||||
std::array<std::vector<gsl::byte>, 4> get_render_targets_data(
|
||||
Surface_color_format surface_color_format, size_t width, size_t height,
|
||||
surface_color_format color_format, size_t width, size_t height,
|
||||
Args&& ...args
|
||||
)
|
||||
{
|
||||
@@ -230,7 +230,7 @@ namespace rsx
|
||||
|
||||
surface_type surface_resource = std::get<1>(m_bound_render_targets[i]);
|
||||
download_data[i] = std::move(
|
||||
Traits::issue_download_command(surface_resource, surface_color_format, width, height, std::forward<Args&&>(args)...)
|
||||
Traits::issue_download_command(surface_resource, color_format, width, height, std::forward<Args&&>(args)...)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -244,50 +244,50 @@ namespace rsx
|
||||
|
||||
gsl::span<const gsl::byte> raw_src = Traits::map_downloaded_buffer(download_data[i], std::forward<Args&&>(args)...);
|
||||
|
||||
size_t src_pitch = utility::get_aligned_pitch(surface_color_format, gsl::narrow<u32>(width));
|
||||
size_t dst_pitch = utility::get_packed_pitch(surface_color_format, gsl::narrow<u32>(width));
|
||||
size_t src_pitch = utility::get_aligned_pitch(color_format, gsl::narrow<u32>(width));
|
||||
size_t dst_pitch = utility::get_packed_pitch(color_format, gsl::narrow<u32>(width));
|
||||
|
||||
result[i].resize(dst_pitch * height);
|
||||
|
||||
// Note: MSVC + GSL doesn't support span<byte> -> span<T> for non const span atm
|
||||
// thus manual conversion
|
||||
switch (surface_color_format)
|
||||
switch (color_format)
|
||||
{
|
||||
case Surface_color_format::a8b8g8r8:
|
||||
case Surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case Surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case Surface_color_format::a8r8g8b8:
|
||||
case Surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case Surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case Surface_color_format::x32:
|
||||
case surface_color_format::a8b8g8r8:
|
||||
case surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case surface_color_format::a8r8g8b8:
|
||||
case surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case surface_color_format::x32:
|
||||
{
|
||||
gsl::span<be_t<u32>> dst_span{ (be_t<u32>*)result[i].data(), gsl::narrow<int>(dst_pitch * width / sizeof(be_t<u32>)) };
|
||||
copy_pitched_src_to_dst(dst_span, gsl::as_span<const u32>(raw_src), src_pitch, width, height);
|
||||
break;
|
||||
}
|
||||
case Surface_color_format::b8:
|
||||
case surface_color_format::b8:
|
||||
{
|
||||
gsl::span<u8> dst_span{ (u8*)result[i].data(), gsl::narrow<int>(dst_pitch * width / sizeof(u8)) };
|
||||
copy_pitched_src_to_dst(dst_span, gsl::as_span<const u8>(raw_src), src_pitch, width, height);
|
||||
break;
|
||||
}
|
||||
case Surface_color_format::g8b8:
|
||||
case Surface_color_format::r5g6b5:
|
||||
case Surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case Surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
case surface_color_format::g8b8:
|
||||
case surface_color_format::r5g6b5:
|
||||
case surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
{
|
||||
gsl::span<be_t<u16>> dst_span{ (be_t<u16>*)result[i].data(), gsl::narrow<int>(dst_pitch * width / sizeof(be_t<u16>)) };
|
||||
copy_pitched_src_to_dst(dst_span, gsl::as_span<const u16>(raw_src), src_pitch, width, height);
|
||||
break;
|
||||
}
|
||||
// Note : may require some big endian swap
|
||||
case Surface_color_format::w32z32y32x32:
|
||||
case surface_color_format::w32z32y32x32:
|
||||
{
|
||||
gsl::span<u128> dst_span{ (u128*)result[i].data(), gsl::narrow<int>(dst_pitch * width / sizeof(u128)) };
|
||||
copy_pitched_src_to_dst(dst_span, gsl::as_span<const u128>(raw_src), src_pitch, width, height);
|
||||
break;
|
||||
}
|
||||
case Surface_color_format::w16z16y16x16:
|
||||
case surface_color_format::w16z16y16x16:
|
||||
{
|
||||
gsl::span<u64> dst_span{ (u64*)result[i].data(), gsl::narrow<int>(dst_pitch * width / sizeof(u64)) };
|
||||
copy_pitched_src_to_dst(dst_span, gsl::as_span<const u64>(raw_src), src_pitch, width, height);
|
||||
@@ -305,7 +305,7 @@ namespace rsx
|
||||
*/
|
||||
template <typename... Args>
|
||||
std::array<std::vector<gsl::byte>, 2> get_depth_stencil_data(
|
||||
Surface_depth_format surface_depth_format, size_t width, size_t height,
|
||||
surface_depth_format depth_format, size_t width, size_t height,
|
||||
Args&& ...args
|
||||
)
|
||||
{
|
||||
@@ -315,18 +315,18 @@ namespace rsx
|
||||
size_t row_pitch = align(width * 4, 256);
|
||||
|
||||
download_buffer_object stencil_data = {};
|
||||
download_buffer_object depth_data = Traits::issue_depth_download_command(std::get<1>(m_bound_depth_stencil), surface_depth_format, width, height, std::forward<Args&&>(args)...);
|
||||
if (surface_depth_format == Surface_depth_format::z24s8)
|
||||
download_buffer_object depth_data = Traits::issue_depth_download_command(std::get<1>(m_bound_depth_stencil), depth_format, width, height, std::forward<Args&&>(args)...);
|
||||
if (depth_format == surface_depth_format::z24s8)
|
||||
stencil_data = std::move(Traits::issue_stencil_download_command(std::get<1>(m_bound_depth_stencil), width, height, std::forward<Args&&>(args)...));
|
||||
|
||||
gsl::span<const gsl::byte> depth_buffer_raw_src = Traits::map_downloaded_buffer(depth_data, std::forward<Args&&>(args)...);
|
||||
if (surface_depth_format == Surface_depth_format::z16)
|
||||
if (depth_format == surface_depth_format::z16)
|
||||
{
|
||||
result[0].resize(width * height * 2);
|
||||
gsl::span<u16> dest{ (u16*)result[0].data(), gsl::narrow<int>(width * height) };
|
||||
copy_pitched_src_to_dst(dest, gsl::as_span<const u16>(depth_buffer_raw_src), row_pitch, width, height);
|
||||
}
|
||||
if (surface_depth_format == Surface_depth_format::z24s8)
|
||||
if (depth_format == surface_depth_format::z24s8)
|
||||
{
|
||||
result[0].resize(width * height * 4);
|
||||
gsl::span<u32> dest{ (u32*)result[0].data(), gsl::narrow<int>(width * height) };
|
||||
@@ -334,7 +334,7 @@ namespace rsx
|
||||
}
|
||||
Traits::unmap_downloaded_buffer(depth_data, std::forward<Args&&>(args)...);
|
||||
|
||||
if (surface_depth_format == Surface_depth_format::z16)
|
||||
if (depth_format == surface_depth_format::z16)
|
||||
return result;
|
||||
|
||||
gsl::span<const gsl::byte> stencil_buffer_raw_src = Traits::map_downloaded_buffer(stencil_data, std::forward<Args&&>(args)...);
|
||||
|
||||
+159
-139
@@ -8,6 +8,65 @@
|
||||
#include "D3D12Formats.h"
|
||||
#include "../rsx_methods.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
UINT get_component_mapping_from_vector_size(u8 size)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
return D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1);
|
||||
case 2:
|
||||
return D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1);
|
||||
case 3:
|
||||
return D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1);
|
||||
case 4:
|
||||
return D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
}
|
||||
throw EXCEPTION("Wrong vector size %d", size);
|
||||
}
|
||||
|
||||
u32 get_vertex_count(const std::vector<std::pair<u32, u32> > first_count_commands)
|
||||
{
|
||||
u32 vertex_count = 0;
|
||||
for (const auto &pair : first_count_commands)
|
||||
vertex_count += pair.second;
|
||||
return vertex_count;
|
||||
}
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC get_vertex_attribute_srv(const rsx::data_array_format_info &info, UINT64 offset_in_vertex_buffers_buffer, UINT buffer_size)
|
||||
{
|
||||
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC vertex_buffer_view = {
|
||||
get_vertex_attribute_format(info.type, info.size),
|
||||
D3D12_SRV_DIMENSION_BUFFER,
|
||||
get_component_mapping_from_vector_size(info.size)
|
||||
};
|
||||
vertex_buffer_view.Buffer.FirstElement = offset_in_vertex_buffers_buffer / element_size;
|
||||
vertex_buffer_view.Buffer.NumElements = buffer_size / element_size;
|
||||
return vertex_buffer_view;
|
||||
}
|
||||
|
||||
template<int N>
|
||||
UINT64 get_next_multiple_of(UINT64 val)
|
||||
{
|
||||
UINT64 divided_val = (val + N - 1) / N;
|
||||
return divided_val * N;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> D3D12GSRender::upload_vertex_attributes(
|
||||
const std::vector<std::pair<u32, u32> > &vertex_ranges,
|
||||
@@ -15,15 +74,9 @@ std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> D3D12GSRender::upload_vertex_attrib
|
||||
{
|
||||
std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> vertex_buffer_views;
|
||||
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertex_buffer_data.Get(), D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, D3D12_RESOURCE_STATE_COPY_DEST));
|
||||
size_t input_slot = 0;
|
||||
|
||||
size_t vertex_count = 0;
|
||||
|
||||
u32 vertex_count = get_vertex_count(vertex_ranges);
|
||||
size_t offset_in_vertex_buffers_buffer = 0;
|
||||
|
||||
for (const auto &pair : vertex_ranges)
|
||||
vertex_count += pair.second;
|
||||
|
||||
u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK];
|
||||
|
||||
for (int index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
@@ -37,9 +90,8 @@ std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> D3D12GSRender::upload_vertex_attrib
|
||||
// Active vertex array
|
||||
const rsx::data_array_format_info &info = vertex_arrays_info[index];
|
||||
|
||||
size_t element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
|
||||
size_t buffer_size = element_size * vertex_count;
|
||||
|
||||
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
|
||||
UINT buffer_size = element_size * vertex_count;
|
||||
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
|
||||
|
||||
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
@@ -52,60 +104,20 @@ std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> D3D12GSRender::upload_vertex_attrib
|
||||
|
||||
command_list->CopyBufferRegion(m_vertex_buffer_data.Get(), offset_in_vertex_buffers_buffer, m_buffer_data.get_heap(), heap_offset, buffer_size);
|
||||
|
||||
UINT component_mapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
switch (info.size)
|
||||
{
|
||||
case 1:
|
||||
component_mapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1,
|
||||
);
|
||||
break;
|
||||
case 2:
|
||||
component_mapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1,
|
||||
);
|
||||
break;
|
||||
case 3:
|
||||
component_mapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1,
|
||||
);
|
||||
break;
|
||||
}
|
||||
vertex_buffer_views.emplace_back(get_vertex_attribute_srv(info, offset_in_vertex_buffers_buffer, buffer_size));
|
||||
offset_in_vertex_buffers_buffer = get_next_multiple_of<48>(offset_in_vertex_buffers_buffer + buffer_size); // 48 is multiple of 2, 4, 6, 8, 12, 16
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC vertex_buffer_view = {
|
||||
get_vertex_attribute_format(info.type, info.size),
|
||||
D3D12_SRV_DIMENSION_BUFFER,
|
||||
component_mapping
|
||||
};
|
||||
vertex_buffer_view.Buffer.FirstElement = offset_in_vertex_buffers_buffer / element_size;
|
||||
vertex_buffer_view.Buffer.NumElements = buffer_size / element_size;
|
||||
vertex_buffer_views.push_back(vertex_buffer_view);
|
||||
|
||||
offset_in_vertex_buffers_buffer = (offset_in_vertex_buffers_buffer + buffer_size + 191) / 192; // 192 is multiple of 2, 4, 6, 8, 12, 16, 24, 32, 48, 64
|
||||
offset_in_vertex_buffers_buffer *= 192;
|
||||
|
||||
m_timers.m_buffer_upload_size += buffer_size;
|
||||
m_timers.buffer_upload_size += buffer_size;
|
||||
|
||||
}
|
||||
else if (register_vertex_info[index].size > 0)
|
||||
{
|
||||
// In register vertex attribute
|
||||
const rsx::data_array_format_info &info = register_vertex_info[index];
|
||||
|
||||
const std::vector<u8> &data = register_vertex_data[index];
|
||||
|
||||
size_t element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
|
||||
size_t buffer_size = data.size();
|
||||
|
||||
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
|
||||
UINT buffer_size = gsl::narrow<UINT>(data.size());
|
||||
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
|
||||
|
||||
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
@@ -114,23 +126,80 @@ std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> D3D12GSRender::upload_vertex_attrib
|
||||
|
||||
command_list->CopyBufferRegion(m_vertex_buffer_data.Get(), offset_in_vertex_buffers_buffer, m_buffer_data.get_heap(), heap_offset, buffer_size);
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC vertex_buffer_view = {
|
||||
get_vertex_attribute_format(info.type, info.size),
|
||||
D3D12_SRV_DIMENSION_BUFFER,
|
||||
D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING
|
||||
};
|
||||
vertex_buffer_view.Buffer.FirstElement = offset_in_vertex_buffers_buffer / element_size;
|
||||
vertex_buffer_view.Buffer.NumElements = buffer_size / element_size;
|
||||
vertex_buffer_views.push_back(vertex_buffer_view);
|
||||
|
||||
offset_in_vertex_buffers_buffer = (offset_in_vertex_buffers_buffer + buffer_size + 191) / 192; // 192 is multiple of 2, 4, 6, 8, 12, 16, 24, 32, 48, 64
|
||||
offset_in_vertex_buffers_buffer *= 192;
|
||||
vertex_buffer_views.emplace_back(get_vertex_attribute_srv(info, offset_in_vertex_buffers_buffer, buffer_size));
|
||||
offset_in_vertex_buffers_buffer = get_next_multiple_of<48>(offset_in_vertex_buffers_buffer + buffer_size); // 48 is multiple of 2, 4, 6, 8, 12, 16
|
||||
}
|
||||
}
|
||||
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertex_buffer_data.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));
|
||||
return vertex_buffer_views;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
std::tuple<std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>, size_t> upload_inlined_vertex_array(
|
||||
gsl::span<const rsx::data_array_format_info, 16> vertex_attribute_infos,
|
||||
gsl::span<const gsl::byte> inlined_array_raw_data,
|
||||
data_heap& ring_buffer_data,
|
||||
ID3D12Resource* vertex_buffer_placement,
|
||||
ID3D12GraphicsCommandList* command_list
|
||||
)
|
||||
{
|
||||
// We can't rely on vertex_attribute_infos strides here so compute it
|
||||
// assuming all attributes are packed
|
||||
u32 stride = 0;
|
||||
for (const auto &info : vertex_attribute_infos)
|
||||
{
|
||||
if (!info.size) // disabled
|
||||
continue;
|
||||
|
||||
stride += rsx::get_vertex_type_size_on_host(info.type, info.size);
|
||||
}
|
||||
|
||||
u32 element_count = gsl::narrow<u32>(inlined_array_raw_data.size_bytes()) / stride;
|
||||
std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> result;
|
||||
|
||||
UINT64 vertex_buffer_offset = 0;
|
||||
for (const auto &info : vertex_attribute_infos)
|
||||
{
|
||||
if (!info.size) // disabled
|
||||
continue;
|
||||
|
||||
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
|
||||
UINT buffer_size = element_size * element_count;
|
||||
size_t heap_offset = ring_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
|
||||
|
||||
void *mapped_buffer = ring_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
gsl::span<gsl::byte> dst = { (gsl::byte*)mapped_buffer, buffer_size };
|
||||
|
||||
for (u32 i = 0; i < element_count; i++)
|
||||
{
|
||||
auto subdst = dst.subspan(i * element_size, element_size);
|
||||
auto subsrc = inlined_array_raw_data.subspan(i * stride, element_size);
|
||||
if (info.type == rsx::vertex_base_type::ub && info.size == 4)
|
||||
{
|
||||
subdst[0] = subsrc[3];
|
||||
subdst[1] = subsrc[2];
|
||||
subdst[2] = subsrc[1];
|
||||
subdst[3] = subsrc[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
std::copy(subsrc.begin(), subsrc.end(), subdst.begin());
|
||||
}
|
||||
}
|
||||
|
||||
ring_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
|
||||
command_list->CopyBufferRegion(vertex_buffer_placement, vertex_buffer_offset, ring_buffer_data.get_heap(), heap_offset, buffer_size);
|
||||
|
||||
result.emplace_back(get_vertex_attribute_srv(info, vertex_buffer_offset, buffer_size));
|
||||
vertex_buffer_offset = get_next_multiple_of<48>(vertex_buffer_offset + buffer_size); // 48 is multiple of 2, 4, 6, 8, 12, 16
|
||||
}
|
||||
|
||||
return std::make_tuple(result, element_count);
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex)
|
||||
{
|
||||
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(256);
|
||||
@@ -140,25 +209,10 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex)
|
||||
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + 256));
|
||||
fill_scale_offset_data(mapped_buffer);
|
||||
int is_alpha_tested = !!(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE]);
|
||||
float alpha_ref = (float&)rsx::method_registers[NV4097_SET_ALPHA_REF];
|
||||
u8 alpha_ref_raw = (u8)(rsx::method_registers[NV4097_SET_ALPHA_REF] & 0xFF);
|
||||
float alpha_ref = alpha_ref_raw / 255.f;
|
||||
memcpy((char*)mapped_buffer + 16 * sizeof(float), &is_alpha_tested, sizeof(int));
|
||||
memcpy((char*)mapped_buffer + 17 * sizeof(float), &alpha_ref, sizeof(float));
|
||||
|
||||
size_t tex_idx = 0;
|
||||
for (u32 i = 0; i < rsx::limits::textures_count; ++i)
|
||||
{
|
||||
if (!textures[i].enabled())
|
||||
{
|
||||
int is_unorm = false;
|
||||
memcpy((char*)mapped_buffer + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int));
|
||||
continue;
|
||||
}
|
||||
size_t w = textures[i].width(), h = textures[i].height();
|
||||
// if (!w || !h) continue;
|
||||
|
||||
int is_unorm = (textures[i].format() & CELL_GCM_TEXTURE_UN);
|
||||
memcpy((char*)mapped_buffer + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int));
|
||||
}
|
||||
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + 256));
|
||||
|
||||
D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = {
|
||||
@@ -167,7 +221,7 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex)
|
||||
};
|
||||
m_device->CreateConstantBufferView(&constant_buffer_view_desc,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
|
||||
.Offset((INT)descriptorIndex, g_descriptor_stride_srv_cbv_uav));
|
||||
.Offset((INT)descriptorIndex, m_descriptor_stride_srv_cbv_uav));
|
||||
}
|
||||
|
||||
void D3D12GSRender::upload_and_bind_vertex_shader_constants(size_t descriptor_index)
|
||||
@@ -186,13 +240,13 @@ void D3D12GSRender::upload_and_bind_vertex_shader_constants(size_t descriptor_in
|
||||
};
|
||||
m_device->CreateConstantBufferView(&constant_buffer_view_desc,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
|
||||
.Offset((INT)descriptor_index, g_descriptor_stride_srv_cbv_uav));
|
||||
.Offset((INT)descriptor_index, m_descriptor_stride_srv_cbv_uav));
|
||||
}
|
||||
|
||||
void D3D12GSRender::upload_and_bind_fragment_shader_constants(size_t descriptor_index)
|
||||
{
|
||||
// Get constant from fragment program
|
||||
size_t buffer_size = m_pso_cache.get_fragment_constants_buffer_size(fragment_program);
|
||||
size_t buffer_size = m_pso_cache.get_fragment_constants_buffer_size(m_fragment_program);
|
||||
// Multiple of 256 never 0
|
||||
buffer_size = (buffer_size + 255) & ~255;
|
||||
|
||||
@@ -200,7 +254,7 @@ void D3D12GSRender::upload_and_bind_fragment_shader_constants(size_t descriptor_
|
||||
|
||||
size_t offset = 0;
|
||||
float *mapped_buffer = m_buffer_data.map<float>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
m_pso_cache.fill_fragment_constans_buffer({ mapped_buffer, gsl::narrow<int>(buffer_size) }, fragment_program);
|
||||
m_pso_cache.fill_fragment_constans_buffer({ mapped_buffer, gsl::narrow<int>(buffer_size) }, m_fragment_program);
|
||||
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
|
||||
D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = {
|
||||
@@ -209,41 +263,11 @@ void D3D12GSRender::upload_and_bind_fragment_shader_constants(size_t descriptor_
|
||||
};
|
||||
m_device->CreateConstantBufferView(&constant_buffer_view_desc,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
|
||||
.Offset((INT)descriptor_index, g_descriptor_stride_srv_cbv_uav));
|
||||
.Offset((INT)descriptor_index, m_descriptor_stride_srv_cbv_uav));
|
||||
}
|
||||
|
||||
|
||||
std::tuple<D3D12_VERTEX_BUFFER_VIEW, size_t> D3D12GSRender::upload_inlined_vertex_array()
|
||||
{
|
||||
UINT offset = 0;
|
||||
|
||||
// Bind attributes
|
||||
for (int index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
{
|
||||
const auto &info = vertex_arrays_info[index];
|
||||
|
||||
if (!info.size) // disabled
|
||||
continue;
|
||||
|
||||
offset += rsx::get_vertex_type_size_on_host(info.type, info.size);
|
||||
}
|
||||
|
||||
// Copy inline buffer
|
||||
size_t buffer_size = inline_vertex_array.size() * sizeof(int);
|
||||
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
|
||||
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
write_inline_array_to_buffer(mapped_buffer);
|
||||
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
|
||||
D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view =
|
||||
{
|
||||
m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
|
||||
(UINT)buffer_size,
|
||||
(UINT)offset
|
||||
};
|
||||
|
||||
return std::make_tuple(vertex_buffer_view, (u32)buffer_size / offset);
|
||||
}
|
||||
|
||||
std::tuple<D3D12_INDEX_BUFFER_VIEW, size_t> D3D12GSRender::generate_index_buffer_for_emulated_primitives_array(const std::vector<std::pair<u32, u32> > &vertex_ranges)
|
||||
{
|
||||
@@ -276,31 +300,30 @@ std::tuple<D3D12_INDEX_BUFFER_VIEW, size_t> D3D12GSRender::generate_index_buffer
|
||||
|
||||
std::tuple<bool, size_t, std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>> D3D12GSRender::upload_and_set_vertex_index_data(ID3D12GraphicsCommandList *command_list)
|
||||
{
|
||||
if (draw_command == Draw_command::draw_command_inlined_array)
|
||||
if (draw_command == rsx::draw_command::inlined_array)
|
||||
{
|
||||
/* size_t vertex_count;
|
||||
D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view;
|
||||
std::tie(vertex_buffer_view, vertex_count) = upload_inlined_vertex_array();
|
||||
command_list->IASetVertexBuffers(0, (UINT)1, &vertex_buffer_view);
|
||||
size_t vertex_count;
|
||||
std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> vertex_buffer_view;
|
||||
std::tie(vertex_buffer_view, vertex_count) = upload_inlined_vertex_array(
|
||||
vertex_arrays_info,
|
||||
{ (const gsl::byte*) inline_vertex_array.data(), gsl::narrow<int>(inline_vertex_array.size() * sizeof(uint)) },
|
||||
m_buffer_data, m_vertex_buffer_data.Get(), command_list);
|
||||
|
||||
if (is_primitive_native(draw_mode))
|
||||
return std::make_tuple(false, vertex_count);
|
||||
return std::make_tuple(false, vertex_count, vertex_buffer_view);
|
||||
|
||||
D3D12_INDEX_BUFFER_VIEW index_buffer_view;
|
||||
size_t index_count;
|
||||
std::tie(index_buffer_view, index_count) = generate_index_buffer_for_emulated_primitives_array({ { 0, (u32)vertex_count } });
|
||||
command_list->IASetIndexBuffer(&index_buffer_view);
|
||||
return std::make_tuple(true, index_count);*/
|
||||
return std::make_tuple(true, index_count, vertex_buffer_view);
|
||||
}
|
||||
|
||||
if (draw_command == Draw_command::draw_command_array)
|
||||
if (draw_command == rsx::draw_command::array)
|
||||
{
|
||||
if (is_primitive_native(draw_mode))
|
||||
{
|
||||
// Index count
|
||||
size_t vertex_count = 0;
|
||||
for (const auto &pair : first_count_commands)
|
||||
vertex_count += pair.second;
|
||||
size_t vertex_count = get_vertex_count(first_count_commands);
|
||||
return std::make_tuple(false, vertex_count, upload_vertex_attributes(first_count_commands, command_list));
|
||||
}
|
||||
|
||||
@@ -311,15 +334,12 @@ std::tuple<bool, size_t, std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>> D3D12GSRe
|
||||
return std::make_tuple(true, index_count, upload_vertex_attributes(first_count_commands, command_list));
|
||||
}
|
||||
|
||||
assert(draw_command == Draw_command::draw_command_indexed);
|
||||
assert(draw_command == rsx::draw_command::indexed);
|
||||
|
||||
// Index count
|
||||
size_t index_count = 0;
|
||||
for (const auto &pair : first_count_commands)
|
||||
index_count += pair.second;
|
||||
index_count = get_index_count(draw_mode, gsl::narrow<int>(index_count));
|
||||
size_t index_count = get_index_count(draw_mode, gsl::narrow<int>(get_vertex_count(first_count_commands)));
|
||||
|
||||
Index_array_type indexed_type = to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
rsx::index_array_type indexed_type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
size_t index_size = get_index_type_size(indexed_type);
|
||||
|
||||
// Alloc
|
||||
@@ -329,13 +349,13 @@ std::tuple<bool, size_t, std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>> D3D12GSRe
|
||||
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
u32 min_index, max_index;
|
||||
|
||||
if (indexed_type == Index_array_type::unsigned_16b)
|
||||
if (indexed_type == rsx::index_array_type::u16)
|
||||
{
|
||||
gsl::span<u16> dst = { (u16*)mapped_buffer, gsl::narrow<int>(buffer_size / index_size) };
|
||||
std::tie(min_index, max_index) = write_index_array_data_to_buffer(dst, draw_mode, first_count_commands);
|
||||
}
|
||||
|
||||
if (indexed_type == Index_array_type::unsigned_32b)
|
||||
if (indexed_type == rsx::index_array_type::u32)
|
||||
{
|
||||
gsl::span<u32> dst = { (u32*)mapped_buffer, gsl::narrow<int>(buffer_size / index_size) };
|
||||
std::tie(min_index, max_index) = write_index_array_data_to_buffer(dst, draw_mode, first_count_commands);
|
||||
@@ -347,7 +367,7 @@ std::tuple<bool, size_t, std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC>> D3D12GSRe
|
||||
(UINT)buffer_size,
|
||||
get_index_type(indexed_type)
|
||||
};
|
||||
m_timers.m_buffer_upload_size += buffer_size;
|
||||
m_timers.buffer_upload_size += buffer_size;
|
||||
command_list->IASetIndexBuffer(&index_buffer_view);
|
||||
|
||||
return std::make_tuple(true, index_count, upload_vertex_attributes({ std::make_pair(0, max_index + 1) }, command_list));
|
||||
|
||||
@@ -42,18 +42,30 @@ std::string getFunctionImp(FUNCTION f)
|
||||
return "float4(1., 1., 1., 1.)";
|
||||
case FUNCTION::FUNCTION_FRACT:
|
||||
return "frac($0)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE:
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D:
|
||||
return "$t.Sample($tsampler, $0.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ:
|
||||
return "$t.Sample($tsampler, ($0.x / $0.w))";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD:
|
||||
return "$t.SampleLevel($tsampler, $0.x, $1)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D:
|
||||
return "$t.Sample($tsampler, $0.xy * $t_scale)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ:
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ:
|
||||
return "$t.Sample($tsampler, ($0.xy / $0.w) * $t_scale)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_LOD:
|
||||
return "$t.SampleLevel($tsampler, ($0.xy / $0.w) * $t_scale, $1)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE:
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD:
|
||||
return "$t.SampleLevel($tsampler, $0.xy * $t_scale, $1)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE:
|
||||
return "$t.Sample($tsampler, $0.xyz)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ:
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ:
|
||||
return "$t.Sample($tsampler, ($0.xyz / $0.w))";
|
||||
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_LOD:
|
||||
return "$t.SampleLevel($tsampler, ($0.xyz / $0.w), $1)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD:
|
||||
return "$t.SampleLevel($tsampler, $0.xyz, $1)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D:
|
||||
return "$t.Sample($tsampler, $0.xyz)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ:
|
||||
return "$t.Sample($tsampler, ($0.xyz / $0.w))";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD:
|
||||
return "$t.SampleLevel($tsampler, $0.xyz, $1)";
|
||||
case FUNCTION::FUNCTION_DFDX:
|
||||
return "ddx($0)";
|
||||
case FUNCTION::FUNCTION_DFDY:
|
||||
@@ -81,4 +93,40 @@ std::string compareFunctionImp(COMPARE f, const std::string &Op0, const std::str
|
||||
return "(" + Op0 + " != " + Op1 + ")";
|
||||
}
|
||||
}
|
||||
|
||||
void insert_d3d12_legacy_function(std::ostream& OS)
|
||||
{
|
||||
OS << "float4 divsq_legacy(float4 num, float4 denum)\n";
|
||||
OS << "{\n";
|
||||
OS << " return num / sqrt(max(denum.xxxx, 1.E-10));\n";
|
||||
OS << "}\n";
|
||||
|
||||
OS << "float4 rcp_legacy(float4 denum)\n";
|
||||
OS << "{\n";
|
||||
OS << " return 1. / denum;\n";
|
||||
OS << "}\n";
|
||||
|
||||
OS << "float4 rsq_legacy(float4 val)\n";
|
||||
OS << "{\n";
|
||||
OS << " return float(1.0 / sqrt(max(val.x, 1.E-10))).xxxx;\n";
|
||||
OS << "}\n\n";
|
||||
|
||||
OS << "float4 log2_legacy(float4 val)\n";
|
||||
OS << "{\n";
|
||||
OS << " return log2(max(val.x, 1.E-10)).xxxx;\n";
|
||||
OS << "}\n\n";
|
||||
|
||||
OS << "float4 lit_legacy(float4 val)";
|
||||
OS << "{\n";
|
||||
OS << " float4 clamped_val = val;\n";
|
||||
OS << " clamped_val.x = max(val.x, 0);\n";
|
||||
OS << " clamped_val.y = max(val.y, 0);\n";
|
||||
OS << " float4 result;\n";
|
||||
OS << " result.x = 1.0;\n";
|
||||
OS << " result.w = 1.;\n";
|
||||
OS << " result.y = clamped_val.x;\n";
|
||||
OS << " result.z = clamped_val.x > 0.0 ? exp(clamped_val.w * log(max(clamped_val.y, 1.E-10))) : 0.0;\n";
|
||||
OS << " return result;\n";
|
||||
OS << "}\n\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -5,3 +5,5 @@
|
||||
std::string getFloatTypeNameImp(size_t elementCount);
|
||||
std::string getFunctionImp(FUNCTION f);
|
||||
std::string compareFunctionImp(COMPARE f, const std::string &Op0, const std::string &Op1);
|
||||
|
||||
void insert_d3d12_legacy_function(std::ostream&);
|
||||
|
||||
@@ -40,10 +40,11 @@ D3D12_BLEND get_blend_factor(u16 factor)
|
||||
case CELL_GCM_SRC_ALPHA_SATURATE: return D3D12_BLEND_SRC_ALPHA_SAT;
|
||||
case CELL_GCM_CONSTANT_COLOR: return D3D12_BLEND_DEST_COLOR;
|
||||
case CELL_GCM_ONE_MINUS_CONSTANT_COLOR: return D3D12_BLEND_INV_DEST_COLOR;
|
||||
case CELL_GCM_CONSTANT_ALPHA: return D3D12_BLEND_DEST_ALPHA;
|
||||
case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: return D3D12_BLEND_INV_DEST_ALPHA;
|
||||
case CELL_GCM_CONSTANT_ALPHA:
|
||||
case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA:
|
||||
break;
|
||||
}
|
||||
throw EXCEPTION("Invalid blend factor (0x%x)", factor);
|
||||
throw EXCEPTION("Invalid or unsupported blend factor (0x%x)", factor);
|
||||
}
|
||||
|
||||
D3D12_BLEND get_blend_factor_alpha(u16 factor)
|
||||
@@ -61,10 +62,10 @@ D3D12_BLEND get_blend_factor_alpha(u16 factor)
|
||||
case CELL_GCM_DST_COLOR: return D3D12_BLEND_DEST_ALPHA;
|
||||
case CELL_GCM_ONE_MINUS_DST_COLOR: return D3D12_BLEND_INV_DEST_ALPHA;
|
||||
case CELL_GCM_SRC_ALPHA_SATURATE: return D3D12_BLEND_SRC_ALPHA_SAT;
|
||||
case CELL_GCM_CONSTANT_ALPHA: return D3D12_BLEND_DEST_ALPHA;
|
||||
case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: return D3D12_BLEND_INV_DEST_ALPHA;
|
||||
case CELL_GCM_CONSTANT_COLOR:
|
||||
case CELL_GCM_ONE_MINUS_CONSTANT_COLOR:
|
||||
case CELL_GCM_CONSTANT_ALPHA:
|
||||
case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA:
|
||||
break;
|
||||
}
|
||||
throw EXCEPTION("Invalid or unsupported blend alpha factor (0x%x)", factor);
|
||||
@@ -161,7 +162,7 @@ DXGI_FORMAT get_texture_format(u8 format)
|
||||
case CELL_GCM_TEXTURE_D8R8G8B8: return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return DXGI_FORMAT_G8R8_G8B8_UNORM;
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return DXGI_FORMAT_R8G8_B8G8_UNORM;
|
||||
case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT;
|
||||
case CELL_GCM_TEXTURE_Y16_X16_FLOAT:
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_HILO8:
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8:
|
||||
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8:
|
||||
@@ -261,99 +262,99 @@ D3D12_FILTER get_texture_filter(u8 min_filter, u8 mag_filter)
|
||||
return D3D12_ENCODE_BASIC_FILTER(min, mag, mip, D3D12_FILTER_REDUCTION_TYPE_STANDARD);
|
||||
}
|
||||
|
||||
D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(Primitive_type draw_mode)
|
||||
D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(rsx::primitive_type draw_mode)
|
||||
{
|
||||
switch (draw_mode)
|
||||
{
|
||||
case Primitive_type::points: return D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
|
||||
case Primitive_type::lines: return D3D_PRIMITIVE_TOPOLOGY_LINELIST;
|
||||
case Primitive_type::line_loop: return D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ;
|
||||
case Primitive_type::line_strip: return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
|
||||
case Primitive_type::triangles: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
case Primitive_type::triangle_strip: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
|
||||
case Primitive_type::triangle_fan: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
case Primitive_type::quads: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
case Primitive_type::quad_strip: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
case Primitive_type::polygon: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
case rsx::primitive_type::points: return D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
|
||||
case rsx::primitive_type::lines: return D3D_PRIMITIVE_TOPOLOGY_LINELIST;
|
||||
case rsx::primitive_type::line_loop: return D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ;
|
||||
case rsx::primitive_type::line_strip: return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
|
||||
case rsx::primitive_type::triangles: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
case rsx::primitive_type::triangle_strip: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
|
||||
case rsx::primitive_type::triangle_fan: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
case rsx::primitive_type::quads: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
case rsx::primitive_type::quad_strip: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
case rsx::primitive_type::polygon: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
}
|
||||
throw EXCEPTION("Invalid draw mode (0x%x)", draw_mode);
|
||||
}
|
||||
|
||||
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(Primitive_type draw_mode)
|
||||
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(rsx::primitive_type draw_mode)
|
||||
{
|
||||
switch (draw_mode)
|
||||
{
|
||||
case Primitive_type::points: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
|
||||
case Primitive_type::lines: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
|
||||
case Primitive_type::line_strip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
|
||||
case Primitive_type::triangles: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case Primitive_type::triangle_strip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case Primitive_type::triangle_fan: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case Primitive_type::quads: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case Primitive_type::quad_strip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case Primitive_type::polygon: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case Primitive_type::line_loop: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
|
||||
case rsx::primitive_type::points: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
|
||||
case rsx::primitive_type::lines: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
|
||||
case rsx::primitive_type::line_strip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
|
||||
case rsx::primitive_type::triangles: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case rsx::primitive_type::triangle_strip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case rsx::primitive_type::triangle_fan: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case rsx::primitive_type::quads: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case rsx::primitive_type::quad_strip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case rsx::primitive_type::polygon: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
case rsx::primitive_type::line_loop: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
|
||||
}
|
||||
throw EXCEPTION("Invalid or unsupported draw mode (0x%x)", draw_mode);
|
||||
}
|
||||
|
||||
DXGI_FORMAT get_color_surface_format(Surface_color_format format)
|
||||
DXGI_FORMAT get_color_surface_format(rsx::surface_color_format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Surface_color_format::r5g6b5: return DXGI_FORMAT_B5G6R5_UNORM;
|
||||
case Surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case Surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case Surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case Surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case rsx::surface_color_format::r5g6b5: return DXGI_FORMAT_B5G6R5_UNORM;
|
||||
case rsx::surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case rsx::surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
return DXGI_FORMAT_B8G8R8X8_UNORM; //BIT.TRIP Runner2 use this
|
||||
case Surface_color_format::a8b8g8r8:
|
||||
case Surface_color_format::a8r8g8b8: return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
case Surface_color_format::b8: return DXGI_FORMAT_R8_UNORM;
|
||||
case Surface_color_format::g8b8: return DXGI_FORMAT_R8G8_UNORM;
|
||||
case Surface_color_format::w16z16y16x16: return DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||
case Surface_color_format::w32z32y32x32: return DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
case Surface_color_format::x32: return DXGI_FORMAT_R32_FLOAT;
|
||||
case rsx::surface_color_format::a8b8g8r8:
|
||||
case rsx::surface_color_format::a8r8g8b8: return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
case rsx::surface_color_format::b8: return DXGI_FORMAT_R8_UNORM;
|
||||
case rsx::surface_color_format::g8b8: return DXGI_FORMAT_R8G8_UNORM;
|
||||
case rsx::surface_color_format::w16z16y16x16: return DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||
case rsx::surface_color_format::w32z32y32x32: return DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
case rsx::surface_color_format::x32: return DXGI_FORMAT_R32_FLOAT;
|
||||
}
|
||||
throw EXCEPTION("Invalid format (0x%x)", format);
|
||||
}
|
||||
|
||||
DXGI_FORMAT get_depth_stencil_surface_format(Surface_depth_format format)
|
||||
DXGI_FORMAT get_depth_stencil_surface_format(rsx::surface_depth_format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM;
|
||||
case Surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||
case rsx::surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM;
|
||||
case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||
}
|
||||
throw EXCEPTION("Invalid format (0x%x)", format);
|
||||
}
|
||||
|
||||
DXGI_FORMAT get_depth_stencil_surface_clear_format(Surface_depth_format format)
|
||||
DXGI_FORMAT get_depth_stencil_surface_clear_format(rsx::surface_depth_format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM;
|
||||
case Surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||
case rsx::surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM;
|
||||
case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||
}
|
||||
throw EXCEPTION("Invalid format (0x%x)", format);
|
||||
}
|
||||
|
||||
DXGI_FORMAT get_depth_stencil_typeless_surface_format(Surface_depth_format format)
|
||||
DXGI_FORMAT get_depth_stencil_typeless_surface_format(rsx::surface_depth_format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Surface_depth_format::z16: return DXGI_FORMAT_R16_TYPELESS;
|
||||
case Surface_depth_format::z24s8: return DXGI_FORMAT_R24G8_TYPELESS;
|
||||
case rsx::surface_depth_format::z16: return DXGI_FORMAT_R16_TYPELESS;
|
||||
case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_R24G8_TYPELESS;
|
||||
}
|
||||
throw EXCEPTION("Invalid format (0x%x)", format);
|
||||
}
|
||||
|
||||
DXGI_FORMAT get_depth_samplable_surface_format(Surface_depth_format format)
|
||||
DXGI_FORMAT get_depth_samplable_surface_format(rsx::surface_depth_format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Surface_depth_format::z16: return DXGI_FORMAT_R16_UNORM;
|
||||
case Surface_depth_format::z24s8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
|
||||
case rsx::surface_depth_format::z16: return DXGI_FORMAT_R16_UNORM;
|
||||
case rsx::surface_depth_format::z24s8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
|
||||
}
|
||||
throw EXCEPTION("Invalid format (0x%x)", format);
|
||||
}
|
||||
@@ -369,21 +370,21 @@ BOOL get_front_face_ccw(u32 ffv)
|
||||
throw EXCEPTION("Invalid front face value (0x%x)", ffv);
|
||||
}
|
||||
|
||||
DXGI_FORMAT get_index_type(Index_array_type index_type)
|
||||
DXGI_FORMAT get_index_type(rsx::index_array_type index_type)
|
||||
{
|
||||
switch (index_type)
|
||||
{
|
||||
case Index_array_type::unsigned_16b: return DXGI_FORMAT_R16_UINT;
|
||||
case Index_array_type::unsigned_32b: return DXGI_FORMAT_R32_UINT;
|
||||
case rsx::index_array_type::u16: return DXGI_FORMAT_R16_UINT;
|
||||
case rsx::index_array_type::u32: return DXGI_FORMAT_R32_UINT;
|
||||
}
|
||||
throw EXCEPTION("Invalid index_type (0x%x)", index_type);
|
||||
}
|
||||
|
||||
DXGI_FORMAT get_vertex_attribute_format(Vertex_base_type type, u8 size)
|
||||
DXGI_FORMAT get_vertex_attribute_format(rsx::vertex_base_type type, u8 size)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Vertex_base_type::s1:
|
||||
case rsx::vertex_base_type::s1:
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
@@ -394,7 +395,7 @@ DXGI_FORMAT get_vertex_attribute_format(Vertex_base_type type, u8 size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Vertex_base_type::f:
|
||||
case rsx::vertex_base_type::f:
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
@@ -405,7 +406,7 @@ DXGI_FORMAT get_vertex_attribute_format(Vertex_base_type type, u8 size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Vertex_base_type::sf:
|
||||
case rsx::vertex_base_type::sf:
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
@@ -416,7 +417,7 @@ DXGI_FORMAT get_vertex_attribute_format(Vertex_base_type type, u8 size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Vertex_base_type::ub:
|
||||
case rsx::vertex_base_type::ub:
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
@@ -427,7 +428,7 @@ DXGI_FORMAT get_vertex_attribute_format(Vertex_base_type type, u8 size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Vertex_base_type::s32k:
|
||||
case rsx::vertex_base_type::s32k:
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
@@ -438,7 +439,7 @@ DXGI_FORMAT get_vertex_attribute_format(Vertex_base_type type, u8 size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Vertex_base_type::cmp:
|
||||
case rsx::vertex_base_type::cmp:
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
@@ -449,7 +450,7 @@ DXGI_FORMAT get_vertex_attribute_format(Vertex_base_type type, u8 size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Vertex_base_type::ub256:
|
||||
case rsx::vertex_base_type::ub256:
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
|
||||
@@ -56,37 +56,37 @@ D3D12_FILTER get_texture_filter(u8 min_filter, u8 mag_filter);
|
||||
/**
|
||||
* Convert draw mode to D3D12_PRIMITIVE_TOPOLOGY
|
||||
*/
|
||||
D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(Primitive_type draw_mode);
|
||||
D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(rsx::primitive_type draw_mode);
|
||||
|
||||
/**
|
||||
* Convert draw mode to D3D12_PRIMITIVE_TOPOLOGY_TYPE
|
||||
*/
|
||||
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(Primitive_type draw_mode);
|
||||
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(rsx::primitive_type draw_mode);
|
||||
|
||||
/**
|
||||
* Convert color surface format to DXGI_FORMAT
|
||||
*/
|
||||
DXGI_FORMAT get_color_surface_format(Surface_color_format format);
|
||||
DXGI_FORMAT get_color_surface_format(rsx::surface_color_format format);
|
||||
|
||||
/**
|
||||
* Convert depth stencil surface format to DXGI_FORMAT
|
||||
*/
|
||||
DXGI_FORMAT get_depth_stencil_surface_format(Surface_depth_format format);
|
||||
DXGI_FORMAT get_depth_stencil_surface_format(rsx::surface_depth_format format);
|
||||
|
||||
/**
|
||||
*Convert depth stencil surface format to DXGI_FORMAT suited for clear value
|
||||
*/
|
||||
DXGI_FORMAT get_depth_stencil_surface_clear_format(Surface_depth_format format);
|
||||
DXGI_FORMAT get_depth_stencil_surface_clear_format(rsx::surface_depth_format format);
|
||||
|
||||
/**
|
||||
* Convert depth surface format to a typeless DXGI_FORMAT
|
||||
*/
|
||||
DXGI_FORMAT get_depth_stencil_typeless_surface_format(Surface_depth_format format);
|
||||
DXGI_FORMAT get_depth_stencil_typeless_surface_format(rsx::surface_depth_format format);
|
||||
|
||||
/**
|
||||
* Convert depth surface format to a DXGI_FORMAT that can be depth sampled
|
||||
*/
|
||||
DXGI_FORMAT get_depth_samplable_surface_format(Surface_depth_format format);
|
||||
DXGI_FORMAT get_depth_samplable_surface_format(rsx::surface_depth_format format);
|
||||
|
||||
/**
|
||||
* Convert front face value to bool value telling wheter front face is counterclockwise or not
|
||||
@@ -96,12 +96,12 @@ BOOL get_front_face_ccw(u32 set_front_face_value);
|
||||
/**
|
||||
* Convert index type to DXGI_FORMAT
|
||||
*/
|
||||
DXGI_FORMAT get_index_type(Index_array_type index_type);
|
||||
DXGI_FORMAT get_index_type(rsx::index_array_type index_type);
|
||||
|
||||
/**
|
||||
* Convert vertex attribute format and size to DXGI_FORMAT
|
||||
*/
|
||||
DXGI_FORMAT get_vertex_attribute_format(Vertex_base_type type, u8 size);
|
||||
DXGI_FORMAT get_vertex_attribute_format(rsx::vertex_base_type type, u8 size);
|
||||
|
||||
/**
|
||||
* Convert scissor register value to D3D12_RECT
|
||||
|
||||
@@ -39,22 +39,6 @@ void D3D12FragmentDecompiler::insertHeader(std::stringstream & OS)
|
||||
OS << " float4x4 scaleOffsetMat;" << std::endl;
|
||||
OS << " int isAlphaTested;" << std::endl;
|
||||
OS << " float alphaRef;" << std::endl;
|
||||
OS << " int tex0_is_unorm;" << std::endl;
|
||||
OS << " int tex1_is_unorm;" << std::endl;
|
||||
OS << " int tex2_is_unorm;" << std::endl;
|
||||
OS << " int tex3_is_unorm;" << std::endl;
|
||||
OS << " int tex4_is_unorm;" << std::endl;
|
||||
OS << " int tex5_is_unorm;" << std::endl;
|
||||
OS << " int tex6_is_unorm;" << std::endl;
|
||||
OS << " int tex7_is_unorm;" << std::endl;
|
||||
OS << " int tex8_is_unorm;" << std::endl;
|
||||
OS << " int tex9_is_unorm;" << std::endl;
|
||||
OS << " int tex10_is_unorm;" << std::endl;
|
||||
OS << " int tex11_is_unorm;" << std::endl;
|
||||
OS << " int tex12_is_unorm;" << std::endl;
|
||||
OS << " int tex13_is_unorm;" << std::endl;
|
||||
OS << " int tex14_is_unorm;" << std::endl;
|
||||
OS << " int tex15_is_unorm;" << std::endl;
|
||||
OS << "};" << std::endl;
|
||||
}
|
||||
|
||||
@@ -107,29 +91,47 @@ void D3D12FragmentDecompiler::insertConstants(std::stringstream & OS)
|
||||
{
|
||||
OS << "cbuffer CONSTANT : register(b2)" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
for (ParamType PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||
for (const ParamType &PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||
{
|
||||
if (PT.type == "sampler2D" || PT.type == "samplerCube")
|
||||
if (PT.type == "sampler1D" || PT.type == "sampler2D" || PT.type == "samplerCube" || PT.type == "sampler3D")
|
||||
continue;
|
||||
for (ParamItem PI : PT.items)
|
||||
for (const ParamItem &PI : PT.items)
|
||||
OS << " " << PT.type << " " << PI.name << ";" << std::endl;
|
||||
}
|
||||
OS << "};" << std::endl << std::endl;
|
||||
|
||||
for (ParamType PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||
for (const ParamType &PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||
{
|
||||
if (PT.type == "sampler2D")
|
||||
if (PT.type == "sampler1D")
|
||||
{
|
||||
for (ParamItem PI : PT.items)
|
||||
for (const ParamItem &PI : PT.items)
|
||||
{
|
||||
size_t textureIndex = atoi(PI.name.data() + 3);
|
||||
OS << "Texture1D " << PI.name << " : register(t" << textureIndex + 16 << ");" << std::endl;
|
||||
OS << "sampler " << PI.name << "sampler : register(s" << textureIndex << ");" << std::endl;
|
||||
}
|
||||
}
|
||||
else if (PT.type == "sampler2D")
|
||||
{
|
||||
for (const ParamItem &PI : PT.items)
|
||||
{
|
||||
size_t textureIndex = atoi(PI.name.data() + 3);
|
||||
OS << "Texture2D " << PI.name << " : register(t" << textureIndex + 16 << ");" << std::endl;
|
||||
OS << "sampler " << PI.name << "sampler : register(s" << textureIndex << ");" << std::endl;
|
||||
}
|
||||
}
|
||||
else if (PT.type == "sampler3D")
|
||||
{
|
||||
for (const ParamItem &PI : PT.items)
|
||||
{
|
||||
size_t textureIndex = atoi(PI.name.data() + 3);
|
||||
OS << "Texture3D " << PI.name << " : register(t" << textureIndex + 16 << ");" << std::endl;
|
||||
OS << "sampler " << PI.name << "sampler : register(s" << textureIndex << ");" << std::endl;
|
||||
}
|
||||
}
|
||||
else if (PT.type == "samplerCube")
|
||||
{
|
||||
for (ParamItem PI : PT.items)
|
||||
for (const ParamItem &PI : PT.items)
|
||||
{
|
||||
size_t textureIndex = atoi(PI.name.data() + 3);
|
||||
OS << "TextureCube " << PI.name << " : register(t" << textureIndex + 16 << ");" << std::endl;
|
||||
@@ -141,57 +143,64 @@ void D3D12FragmentDecompiler::insertConstants(std::stringstream & OS)
|
||||
|
||||
void D3D12FragmentDecompiler::insertMainStart(std::stringstream & OS)
|
||||
{
|
||||
// "lib" function
|
||||
// 0.00001 is used as "some non zero very little number"
|
||||
OS << "float4 divsq_legacy(float4 num, float4 denum)\n";
|
||||
OS << "{\n";
|
||||
OS << " return num / sqrt(max(denum.xxxx, 0.00001));\n";
|
||||
OS << "}\n";
|
||||
|
||||
OS << "float4 rcp_legacy(float4 denum)\n";
|
||||
OS << "{\n";
|
||||
OS << " return 1. / denum;\n";
|
||||
OS << "}\n";
|
||||
|
||||
OS << "float4 rsq_legacy(float4 denum)\n";
|
||||
OS << "{\n";
|
||||
OS << " return 1. / sqrt(max(denum, 0.00001));\n";
|
||||
OS << "}\n";
|
||||
|
||||
insert_d3d12_legacy_function(OS);
|
||||
|
||||
const std::set<std::string> output_value =
|
||||
{
|
||||
"r0", "r1", "r2", "r3", "r4",
|
||||
"h0", "h2", "h4", "h6", "h8"
|
||||
};
|
||||
OS << "void ps_impl(PixelInput In, inout float4 r0, inout float4 h0, inout float4 r1, inout float4 h2, inout float4 r2, inout float4 h4, inout float4 r3, inout float4 h6, inout float4 r4, inout float4 h8)" << std::endl;
|
||||
OS << "void ps_impl(bool is_front_face, PixelInput In, inout float4 r0, inout float4 h0, inout float4 r1, inout float4 h2, inout float4 r2, inout float4 h4, inout float4 r3, inout float4 h6, inout float4 r4, inout float4 h8)" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
for (ParamType PT : m_parr.params[PF_PARAM_IN])
|
||||
for (const ParamType &PT : m_parr.params[PF_PARAM_IN])
|
||||
{
|
||||
for (ParamItem PI : PT.items)
|
||||
for (const ParamItem &PI : PT.items)
|
||||
{
|
||||
if (m_prog.front_back_color_enabled)
|
||||
{
|
||||
if (PI.name == "spec_color" && m_prog.back_color_specular_output)
|
||||
{
|
||||
OS << " float4 spec_color = is_front_face ? In.dst_reg4 : In.spec_color;\n";
|
||||
continue;
|
||||
}
|
||||
if (PI.name == "diff_color" && m_prog.back_color_diffuse_output)
|
||||
{
|
||||
OS << " float4 diff_color = is_front_face ? In.dst_reg3 : In.diff_color;\n";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
OS << " " << PT.type << " " << PI.name << " = In." << PI.name << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
// A bit unclean, but works.
|
||||
OS << " " << "float4 gl_Position = In.Position;" << std::endl;
|
||||
OS << " " << "float4 gl_FragCoord = In.Position;" << std::endl;
|
||||
if (m_prog.origin_mode == rsx::window_origin::bottom)
|
||||
OS << " gl_FragCoord.y = (" << std::to_string(m_prog.height) << " - gl_FragCoord.y);\n";
|
||||
// Declare output
|
||||
for (ParamType PT : m_parr.params[PF_PARAM_NONE])
|
||||
for (const ParamType &PT : m_parr.params[PF_PARAM_NONE])
|
||||
{
|
||||
for (ParamItem PI : PT.items)
|
||||
for (const ParamItem &PI : PT.items)
|
||||
if (output_value.find(PI.name) == output_value.end())
|
||||
OS << " " << PT.type << " " << PI.name << " = float4(0., 0., 0., 0.);" << std::endl;
|
||||
}
|
||||
// Declare texture coordinate scaling component (to handle unormalized texture coordinates)
|
||||
|
||||
for (ParamType PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||
for (const ParamType &PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||
{
|
||||
if (PT.type != "sampler2D")
|
||||
continue;
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
size_t textureIndex = atoi(PI.name.data() + 3);
|
||||
bool is_unorm = !!(m_prog.unnormalized_coords & (1 << textureIndex));
|
||||
if (!is_unorm)
|
||||
{
|
||||
OS << " float2 " << PI.name << "_scale = float2(1., 1.);" << std::endl;
|
||||
continue;
|
||||
}
|
||||
OS << " float2 " << PI.name << "_dim;" << std::endl;
|
||||
OS << " " << PI.name << ".GetDimensions(" << PI.name << "_dim.x, " << PI.name << "_dim.y);" << std::endl;
|
||||
OS << " float2 " << PI.name << "_scale = (!!" << PI.name << "_is_unorm) ? float2(1., 1.) / " << PI.name << "_dim : float2(1., 1.);" << std::endl;
|
||||
OS << " float2 " << PI.name << "_scale = float2(1., 1.) / " << PI.name << "_dim;" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,7 +209,7 @@ void D3D12FragmentDecompiler::insertMainEnd(std::stringstream & OS)
|
||||
{
|
||||
OS << "}" << std::endl;
|
||||
OS << std::endl;
|
||||
OS << "PixelOutput main(PixelInput In)" << std::endl;
|
||||
OS << "PixelOutput main(PixelInput In, bool is_front_face : SV_IsFrontFace)" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
OS << " float4 r0 = float4(0., 0., 0., 0.);" << std::endl;
|
||||
OS << " float4 r1 = float4(0., 0., 0., 0.);" << std::endl;
|
||||
@@ -212,7 +221,7 @@ void D3D12FragmentDecompiler::insertMainEnd(std::stringstream & OS)
|
||||
OS << " float4 h4 = float4(0., 0., 0., 0.);" << std::endl;
|
||||
OS << " float4 h6 = float4(0., 0., 0., 0.);" << std::endl;
|
||||
OS << " float4 h8 = float4(0., 0., 0., 0.);" << std::endl;
|
||||
OS << " ps_impl(In, r0, h0, r1, h2, r2, h4, r3, h6, r4, h8);" << std::endl;
|
||||
OS << " ps_impl(is_front_face, In, r0, h0, r1, h2, r2, h4, r3, h6, r4, h8);" << std::endl;
|
||||
|
||||
const std::pair<std::string, std::string> table[] =
|
||||
{
|
||||
@@ -244,7 +253,30 @@ void D3D12FragmentDecompiler::insertMainEnd(std::stringstream & OS)
|
||||
}
|
||||
// Shaders don't always output colors (for instance if they write to depth only)
|
||||
if (!first_output_name.empty())
|
||||
OS << " if (isAlphaTested && Out." << first_output_name << ".a <= alphaRef) discard;\n";
|
||||
{
|
||||
switch (m_prog.alpha_func)
|
||||
{
|
||||
case rsx::comparaison_function::equal:
|
||||
OS << " if (isAlphaTested && Out." << first_output_name << ".a != alphaRef) discard;\n";
|
||||
break;
|
||||
case rsx::comparaison_function::not_equal:
|
||||
OS << " if (isAlphaTested && Out." << first_output_name << ".a == alphaRef) discard;\n";
|
||||
break;
|
||||
case rsx::comparaison_function::less_or_equal:
|
||||
OS << " if (isAlphaTested && Out." << first_output_name << ".a > alphaRef) discard;\n";
|
||||
break;
|
||||
case rsx::comparaison_function::less:
|
||||
OS << " if (isAlphaTested && Out." << first_output_name << ".a >= alphaRef) discard;\n";
|
||||
break;
|
||||
case rsx::comparaison_function::greater:
|
||||
OS << " if (isAlphaTested && Out." << first_output_name << ".a <= alphaRef) discard;\n";
|
||||
break;
|
||||
case rsx::comparaison_function::greater_or_equal:
|
||||
OS << " if (isAlphaTested && Out." << first_output_name << ".a < alphaRef) discard;\n";
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
OS << " return Out;" << std::endl;
|
||||
OS << "}" << std::endl;
|
||||
}
|
||||
|
||||
@@ -58,17 +58,15 @@ void wait_for_command_queue(ID3D12Device *device, ID3D12CommandQueue *command_qu
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12GSRender::Shader::Release()
|
||||
void D3D12GSRender::shader::release()
|
||||
{
|
||||
m_PSO->Release();
|
||||
m_rootSignature->Release();
|
||||
m_vertexBuffer->Release();
|
||||
m_textureDescriptorHeap->Release();
|
||||
m_samplerDescriptorHeap->Release();
|
||||
pso->Release();
|
||||
root_signature->Release();
|
||||
vertex_buffer->Release();
|
||||
texture_descriptor_heap->Release();
|
||||
sampler_descriptor_heap->Release();
|
||||
}
|
||||
|
||||
extern std::function<bool(u32 addr)> gfxHandler;
|
||||
|
||||
bool D3D12GSRender::invalidate_address(u32 addr)
|
||||
{
|
||||
bool result = false;
|
||||
@@ -89,12 +87,6 @@ D3D12DLLManagement::~D3D12DLLManagement()
|
||||
D3D12GSRender::D3D12GSRender()
|
||||
: GSRender(frame_type::DX12), m_d3d12_lib(), m_current_pso({})
|
||||
{
|
||||
gfxHandler = [this](u32 addr) {
|
||||
bool result = invalidate_address(addr);
|
||||
if (result)
|
||||
LOG_WARNING(RSX, "Reporting Cell writing to 0x%x", addr);
|
||||
return result;
|
||||
};
|
||||
if (rpcs3::config.rsx.d3d12.debug_output.value())
|
||||
{
|
||||
Microsoft::WRL::ComPtr<ID3D12Debug> debugInterface;
|
||||
@@ -113,10 +105,10 @@ D3D12GSRender::D3D12GSRender()
|
||||
D3D12_COMMAND_QUEUE_DESC graphic_queue_desc = { D3D12_COMMAND_LIST_TYPE_DIRECT };
|
||||
CHECK_HRESULT(m_device->CreateCommandQueue(&graphic_queue_desc, IID_PPV_ARGS(m_command_queue.GetAddressOf())));
|
||||
|
||||
g_descriptor_stride_srv_cbv_uav = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
g_descriptor_stride_dsv = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
|
||||
g_descriptor_stride_rtv = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||
g_descriptor_stride_samplers = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
|
||||
m_descriptor_stride_srv_cbv_uav = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
m_descriptor_stride_dsv = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
|
||||
m_descriptor_stride_rtv = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||
m_descriptor_stride_samplers = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
|
||||
|
||||
// Create swap chain and put them in a descriptor heap as rendertarget
|
||||
DXGI_SWAP_CHAIN_DESC swap_chain = {};
|
||||
@@ -161,7 +153,7 @@ D3D12GSRender::D3D12GSRender()
|
||||
CD3DX12_DESCRIPTOR_RANGE(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, texture_count, 0),
|
||||
};
|
||||
CD3DX12_ROOT_PARAMETER RP[2];
|
||||
size_t cbv_srv_uav_descriptor_size = 4;
|
||||
UINT cbv_srv_uav_descriptor_size = 4;
|
||||
if (texture_count == 0)
|
||||
cbv_srv_uav_descriptor_size -= 1;
|
||||
if (vertex_buffer_count == 0)
|
||||
@@ -187,8 +179,8 @@ D3D12GSRender::D3D12GSRender()
|
||||
m_per_frame_storage[1].init(m_device.Get());
|
||||
m_per_frame_storage[1].reset();
|
||||
|
||||
initConvertShader();
|
||||
m_output_scaling_pass.Init(m_device.Get(), m_command_queue.Get());
|
||||
init_convert_shader();
|
||||
m_output_scaling_pass.init(m_device.Get(), m_command_queue.Get());
|
||||
|
||||
CHECK_HRESULT(
|
||||
m_device->CreateCommittedResource(
|
||||
@@ -225,13 +217,12 @@ D3D12GSRender::~D3D12GSRender()
|
||||
|
||||
m_texture_cache.unprotect_all();
|
||||
|
||||
gfxHandler = [this](u32) { return false; };
|
||||
m_dummy_texture->Release();
|
||||
m_convertPSO->Release();
|
||||
m_convertRootSignature->Release();
|
||||
m_convert_pso->Release();
|
||||
m_convert_root_signature->Release();
|
||||
m_per_frame_storage[0].release();
|
||||
m_per_frame_storage[1].release();
|
||||
m_output_scaling_pass.Release();
|
||||
m_output_scaling_pass.release();
|
||||
|
||||
release_d2d_structures();
|
||||
}
|
||||
@@ -267,7 +258,7 @@ void D3D12GSRender::end()
|
||||
prepare_render_targets(get_current_resource_storage().command_list.Get());
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> rtt_duration_end = std::chrono::system_clock::now();
|
||||
m_timers.m_prepare_rtt_duration += std::chrono::duration_cast<std::chrono::microseconds>(rtt_duration_end - rtt_duration_start).count();
|
||||
m_timers.prepare_rtt_duration += std::chrono::duration_cast<std::chrono::microseconds>(rtt_duration_end - rtt_duration_start).count();
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> vertex_index_duration_start = std::chrono::system_clock::now();
|
||||
|
||||
@@ -281,24 +272,24 @@ void D3D12GSRender::end()
|
||||
size_t vertex_buffer_count = vertex_buffer_views.size();
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> vertex_index_duration_end = std::chrono::system_clock::now();
|
||||
m_timers.m_vertex_index_duration += std::chrono::duration_cast<std::chrono::microseconds>(vertex_index_duration_end - vertex_index_duration_start).count();
|
||||
m_timers.vertex_index_duration += std::chrono::duration_cast<std::chrono::microseconds>(vertex_index_duration_end - vertex_index_duration_start).count();
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> program_load_start = std::chrono::system_clock::now();
|
||||
load_program();
|
||||
std::chrono::time_point<std::chrono::system_clock> program_load_end = std::chrono::system_clock::now();
|
||||
m_timers.m_program_load_duration += std::chrono::duration_cast<std::chrono::microseconds>(program_load_end - program_load_start).count();
|
||||
m_timers.program_load_duration += std::chrono::duration_cast<std::chrono::microseconds>(program_load_end - program_load_start).count();
|
||||
|
||||
get_current_resource_storage().command_list->SetGraphicsRootSignature(m_root_signatures[std::get<2>(m_current_pso)][vertex_buffer_count].Get());
|
||||
get_current_resource_storage().command_list->OMSetStencilRef(rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF]);
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> constants_duration_start = std::chrono::system_clock::now();
|
||||
|
||||
size_t offset = 0;
|
||||
INT offset = 0;
|
||||
for (const auto view : vertex_buffer_views)
|
||||
{
|
||||
m_device->CreateShaderResourceView(m_vertex_buffer_data.Get(), &view,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
|
||||
.Offset((INT)currentDescriptorIndex + offset++, g_descriptor_stride_srv_cbv_uav));
|
||||
.Offset((INT)currentDescriptorIndex + offset++, m_descriptor_stride_srv_cbv_uav));
|
||||
}
|
||||
|
||||
// Constants
|
||||
@@ -307,22 +298,37 @@ void D3D12GSRender::end()
|
||||
upload_and_bind_fragment_shader_constants(currentDescriptorIndex + 2 + vertex_buffer_count);
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> constants_duration_end = std::chrono::system_clock::now();
|
||||
m_timers.m_constants_duration += std::chrono::duration_cast<std::chrono::microseconds>(constants_duration_end - constants_duration_start).count();
|
||||
m_timers.constants_duration += std::chrono::duration_cast<std::chrono::microseconds>(constants_duration_end - constants_duration_start).count();
|
||||
|
||||
get_current_resource_storage().command_list->SetPipelineState(std::get<0>(m_current_pso).Get());
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> texture_duration_start = std::chrono::system_clock::now();
|
||||
if (std::get<2>(m_current_pso) > 0)
|
||||
size_t texture_count = std::get<2>(m_current_pso);
|
||||
if (texture_count > 0)
|
||||
{
|
||||
upload_and_bind_textures(get_current_resource_storage().command_list.Get(), currentDescriptorIndex + 3 + vertex_buffer_count, std::get<2>(m_current_pso) > 0);
|
||||
upload_and_bind_textures(get_current_resource_storage().command_list.Get(), texture_count);
|
||||
|
||||
for (unsigned i = 0; i < texture_count; i++)
|
||||
{
|
||||
ID3D12Resource *tex_resource;
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srv;
|
||||
std::tie(tex_resource, srv) = m_current_shader_resources[i];
|
||||
m_device->CreateShaderResourceView(tex_resource, &srv,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
|
||||
.Offset((INT)currentDescriptorIndex + 3 + (INT)vertex_buffer_count + (INT)i, m_descriptor_stride_srv_cbv_uav)
|
||||
);
|
||||
m_device->CreateSampler(&m_current_samplers[i],
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().sampler_descriptor_heap[get_current_resource_storage().sampler_descriptors_heap_index]->GetCPUDescriptorHandleForHeapStart())
|
||||
.Offset((UINT)get_current_resource_storage().current_sampler_index + (UINT)i, m_descriptor_stride_samplers));
|
||||
}
|
||||
|
||||
get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(0,
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetGPUDescriptorHandleForHeapStart())
|
||||
.Offset((INT)currentDescriptorIndex, g_descriptor_stride_srv_cbv_uav)
|
||||
.Offset((INT)currentDescriptorIndex, m_descriptor_stride_srv_cbv_uav)
|
||||
);
|
||||
get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(1,
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().sampler_descriptor_heap[get_current_resource_storage().sampler_descriptors_heap_index]->GetGPUDescriptorHandleForHeapStart())
|
||||
.Offset((INT)get_current_resource_storage().current_sampler_index, g_descriptor_stride_samplers)
|
||||
.Offset((INT)get_current_resource_storage().current_sampler_index, m_descriptor_stride_samplers)
|
||||
);
|
||||
|
||||
get_current_resource_storage().current_sampler_index += std::get<2>(m_current_pso);
|
||||
@@ -332,13 +338,13 @@ void D3D12GSRender::end()
|
||||
{
|
||||
get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(0,
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetGPUDescriptorHandleForHeapStart())
|
||||
.Offset((INT)currentDescriptorIndex, g_descriptor_stride_srv_cbv_uav)
|
||||
.Offset((INT)currentDescriptorIndex, m_descriptor_stride_srv_cbv_uav)
|
||||
);
|
||||
get_current_resource_storage().descriptors_heap_index += 3 + vertex_buffer_count;
|
||||
}
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> texture_duration_end = std::chrono::system_clock::now();
|
||||
m_timers.m_texture_duration += std::chrono::duration_cast<std::chrono::microseconds>(texture_duration_end - texture_duration_start).count();
|
||||
m_timers.texture_duration += std::chrono::duration_cast<std::chrono::microseconds>(texture_duration_end - texture_duration_start).count();
|
||||
set_rtt_and_ds(get_current_resource_storage().command_list.Get());
|
||||
|
||||
int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16;
|
||||
@@ -365,8 +371,8 @@ void D3D12GSRender::end()
|
||||
get_current_resource_storage().command_list->DrawInstanced((UINT)vertex_count, 1, 0, 0);
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> end_duration = std::chrono::system_clock::now();
|
||||
m_timers.m_draw_calls_duration += std::chrono::duration_cast<std::chrono::microseconds>(end_duration - start_duration).count();
|
||||
m_timers.m_draw_calls_count++;
|
||||
m_timers.draw_calls_duration += std::chrono::duration_cast<std::chrono::microseconds>(end_duration - start_duration).count();
|
||||
m_timers.draw_calls_count++;
|
||||
|
||||
if (rpcs3::config.rsx.d3d12.debug_output.value())
|
||||
{
|
||||
@@ -379,17 +385,17 @@ void D3D12GSRender::end()
|
||||
|
||||
namespace
|
||||
{
|
||||
bool is_flip_surface_in_global_memory(Surface_target color_target)
|
||||
bool is_flip_surface_in_global_memory(rsx::surface_target color_target)
|
||||
{
|
||||
switch (color_target)
|
||||
{
|
||||
case Surface_target::surface_a:
|
||||
case Surface_target::surface_b:
|
||||
case Surface_target::surfaces_a_b:
|
||||
case Surface_target::surfaces_a_b_c:
|
||||
case Surface_target::surfaces_a_b_c_d:
|
||||
case rsx::surface_target::surface_a:
|
||||
case rsx::surface_target::surface_b:
|
||||
case rsx::surface_target::surfaces_a_b:
|
||||
case rsx::surface_target::surfaces_a_b_c:
|
||||
case rsx::surface_target::surfaces_a_b_c_d:
|
||||
return true;
|
||||
case Surface_target::none:
|
||||
case rsx::surface_target::none:
|
||||
return false;
|
||||
}
|
||||
throw EXCEPTION("Wrong color_target");
|
||||
@@ -401,7 +407,7 @@ void D3D12GSRender::flip(int buffer)
|
||||
ID3D12Resource *resource_to_flip;
|
||||
float viewport_w, viewport_h;
|
||||
|
||||
if (!is_flip_surface_in_global_memory(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])))
|
||||
if (!is_flip_surface_in_global_memory(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])))
|
||||
{
|
||||
resource_storage &storage = get_current_resource_storage();
|
||||
assert(storage.ram_framebuffer == nullptr);
|
||||
@@ -482,15 +488,15 @@ void D3D12GSRender::flip(int buffer)
|
||||
(LONG)m_backbuffer[m_swap_chain->GetCurrentBackBufferIndex()]->GetDesc().Height,
|
||||
};
|
||||
get_current_resource_storage().command_list->RSSetScissorRects(1, &box);
|
||||
get_current_resource_storage().command_list->SetGraphicsRootSignature(m_output_scaling_pass.m_rootSignature);
|
||||
get_current_resource_storage().command_list->SetPipelineState(m_output_scaling_pass.m_PSO);
|
||||
get_current_resource_storage().command_list->SetGraphicsRootSignature(m_output_scaling_pass.root_signature);
|
||||
get_current_resource_storage().command_list->SetPipelineState(m_output_scaling_pass.pso);
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC shader_resource_view_desc = {};
|
||||
// FIXME: Not always true
|
||||
shader_resource_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
shader_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
shader_resource_view_desc.Texture2D.MipLevels = 1;
|
||||
if (is_flip_surface_in_global_memory(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])))
|
||||
if (is_flip_surface_in_global_memory(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])))
|
||||
shader_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
else
|
||||
shader_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
|
||||
@@ -500,7 +506,7 @@ void D3D12GSRender::flip(int buffer)
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0
|
||||
);
|
||||
m_device->CreateShaderResourceView(resource_to_flip, &shader_resource_view_desc,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(m_output_scaling_pass.m_textureDescriptorHeap->GetCPUDescriptorHandleForHeapStart()).Offset(m_swap_chain->GetCurrentBackBufferIndex(), g_descriptor_stride_srv_cbv_uav));
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(m_output_scaling_pass.texture_descriptor_heap->GetCPUDescriptorHandleForHeapStart()).Offset(m_swap_chain->GetCurrentBackBufferIndex(), m_descriptor_stride_srv_cbv_uav));
|
||||
|
||||
D3D12_SAMPLER_DESC sampler_desc = {};
|
||||
sampler_desc.Filter = D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT;
|
||||
@@ -508,24 +514,24 @@ void D3D12GSRender::flip(int buffer)
|
||||
sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||
sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||
m_device->CreateSampler(&sampler_desc,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(m_output_scaling_pass.m_samplerDescriptorHeap->GetCPUDescriptorHandleForHeapStart()).Offset(m_swap_chain->GetCurrentBackBufferIndex(), g_descriptor_stride_samplers));
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(m_output_scaling_pass.sampler_descriptor_heap->GetCPUDescriptorHandleForHeapStart()).Offset(m_swap_chain->GetCurrentBackBufferIndex(), m_descriptor_stride_samplers));
|
||||
|
||||
ID3D12DescriptorHeap *descriptors_heaps[] =
|
||||
{
|
||||
m_output_scaling_pass.m_textureDescriptorHeap,
|
||||
m_output_scaling_pass.m_samplerDescriptorHeap
|
||||
m_output_scaling_pass.texture_descriptor_heap,
|
||||
m_output_scaling_pass.sampler_descriptor_heap
|
||||
};
|
||||
get_current_resource_storage().command_list->SetDescriptorHeaps(2, descriptors_heaps);
|
||||
get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(0,
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE(m_output_scaling_pass.m_textureDescriptorHeap->GetGPUDescriptorHandleForHeapStart()).Offset(m_swap_chain->GetCurrentBackBufferIndex(), g_descriptor_stride_srv_cbv_uav));
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE(m_output_scaling_pass.texture_descriptor_heap->GetGPUDescriptorHandleForHeapStart()).Offset(m_swap_chain->GetCurrentBackBufferIndex(), m_descriptor_stride_srv_cbv_uav));
|
||||
get_current_resource_storage().command_list->SetGraphicsRootDescriptorTable(1,
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE(m_output_scaling_pass.m_samplerDescriptorHeap->GetGPUDescriptorHandleForHeapStart()).Offset(m_swap_chain->GetCurrentBackBufferIndex(), g_descriptor_stride_samplers));
|
||||
CD3DX12_GPU_DESCRIPTOR_HANDLE(m_output_scaling_pass.sampler_descriptor_heap->GetGPUDescriptorHandleForHeapStart()).Offset(m_swap_chain->GetCurrentBackBufferIndex(), m_descriptor_stride_samplers));
|
||||
|
||||
get_current_resource_storage().command_list->OMSetRenderTargets(1,
|
||||
&CD3DX12_CPU_DESCRIPTOR_HANDLE(m_backbuffer_descriptor_heap[m_swap_chain->GetCurrentBackBufferIndex()]->GetCPUDescriptorHandleForHeapStart()),
|
||||
true, nullptr);
|
||||
D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view = {};
|
||||
vertex_buffer_view.BufferLocation = m_output_scaling_pass.m_vertexBuffer->GetGPUVirtualAddress();
|
||||
vertex_buffer_view.BufferLocation = m_output_scaling_pass.vertex_buffer->GetGPUVirtualAddress();
|
||||
vertex_buffer_view.StrideInBytes = 4 * sizeof(float);
|
||||
vertex_buffer_view.SizeInBytes = 16 * sizeof(float);
|
||||
get_current_resource_storage().command_list->IASetVertexBuffers(0, 1, &vertex_buffer_view);
|
||||
@@ -535,7 +541,7 @@ void D3D12GSRender::flip(int buffer)
|
||||
|
||||
if (!rpcs3::config.rsx.d3d12.overlay.value())
|
||||
get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backbuffer[m_swap_chain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
|
||||
if (is_flip_surface_in_global_memory(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) && resource_to_flip != nullptr)
|
||||
if (is_flip_surface_in_global_memory(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) && resource_to_flip != nullptr)
|
||||
get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(resource_to_flip, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET));
|
||||
CHECK_HRESULT(get_current_resource_storage().command_list->Close());
|
||||
m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
|
||||
@@ -580,20 +586,36 @@ void D3D12GSRender::flip(int buffer)
|
||||
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> flip_end = std::chrono::system_clock::now();
|
||||
m_timers.m_flip_duration += std::chrono::duration_cast<std::chrono::microseconds>(flip_end - flip_start).count();
|
||||
m_timers.flip_duration += std::chrono::duration_cast<std::chrono::microseconds>(flip_end - flip_start).count();
|
||||
}
|
||||
|
||||
bool D3D12GSRender::on_access_violation(u32 address, bool is_writing)
|
||||
{
|
||||
if (!is_writing)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (invalidate_address(address))
|
||||
{
|
||||
LOG_WARNING(RSX, "Reporting Cell writing to 0x%x", address);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void D3D12GSRender::reset_timer()
|
||||
{
|
||||
m_timers.m_draw_calls_count = 0;
|
||||
m_timers.m_draw_calls_duration = 0;
|
||||
m_timers.m_prepare_rtt_duration = 0;
|
||||
m_timers.m_vertex_index_duration = 0;
|
||||
m_timers.m_buffer_upload_size = 0;
|
||||
m_timers.m_program_load_duration = 0;
|
||||
m_timers.m_constants_duration = 0;
|
||||
m_timers.m_texture_duration = 0;
|
||||
m_timers.m_flip_duration = 0;
|
||||
m_timers.draw_calls_count = 0;
|
||||
m_timers.draw_calls_duration = 0;
|
||||
m_timers.prepare_rtt_duration = 0;
|
||||
m_timers.vertex_index_duration = 0;
|
||||
m_timers.buffer_upload_size = 0;
|
||||
m_timers.program_load_duration = 0;
|
||||
m_timers.constants_duration = 0;
|
||||
m_timers.texture_duration = 0;
|
||||
m_timers.flip_duration = 0;
|
||||
}
|
||||
|
||||
resource_storage& D3D12GSRender::get_current_resource_storage()
|
||||
|
||||
@@ -64,49 +64,49 @@ private:
|
||||
|
||||
rsx::surface_info m_surface;
|
||||
|
||||
RSXVertexProgram vertex_program;
|
||||
RSXFragmentProgram fragment_program;
|
||||
RSXVertexProgram m_vertex_program;
|
||||
RSXFragmentProgram m_fragment_program;
|
||||
PipelineStateObjectCache m_pso_cache;
|
||||
std::tuple<ComPtr<ID3D12PipelineState>, size_t, size_t> m_current_pso;
|
||||
|
||||
struct
|
||||
{
|
||||
size_t m_draw_calls_duration;
|
||||
size_t m_draw_calls_count;
|
||||
size_t m_prepare_rtt_duration;
|
||||
size_t m_vertex_index_duration;
|
||||
size_t m_buffer_upload_size;
|
||||
size_t m_program_load_duration;
|
||||
size_t m_constants_duration;
|
||||
size_t m_texture_duration;
|
||||
size_t m_flip_duration;
|
||||
size_t draw_calls_duration;
|
||||
size_t draw_calls_count;
|
||||
size_t prepare_rtt_duration;
|
||||
size_t vertex_index_duration;
|
||||
size_t buffer_upload_size;
|
||||
size_t program_load_duration;
|
||||
size_t constants_duration;
|
||||
size_t texture_duration;
|
||||
size_t flip_duration;
|
||||
} m_timers;
|
||||
|
||||
void reset_timer();
|
||||
|
||||
struct Shader
|
||||
struct shader
|
||||
{
|
||||
ID3D12PipelineState *m_PSO;
|
||||
ID3D12RootSignature *m_rootSignature;
|
||||
ID3D12Resource *m_vertexBuffer;
|
||||
ID3D12DescriptorHeap *m_textureDescriptorHeap;
|
||||
ID3D12DescriptorHeap *m_samplerDescriptorHeap;
|
||||
void Init(ID3D12Device *device, ID3D12CommandQueue *gfxcommandqueue);
|
||||
void Release();
|
||||
ID3D12PipelineState *pso;
|
||||
ID3D12RootSignature *root_signature;
|
||||
ID3D12Resource *vertex_buffer;
|
||||
ID3D12DescriptorHeap *texture_descriptor_heap;
|
||||
ID3D12DescriptorHeap *sampler_descriptor_heap;
|
||||
void init(ID3D12Device *device, ID3D12CommandQueue *gfx_command_queue);
|
||||
void release();
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores data related to the scaling pass that turns internal
|
||||
* render targets into presented buffers.
|
||||
*/
|
||||
Shader m_output_scaling_pass;
|
||||
shader m_output_scaling_pass;
|
||||
|
||||
/**
|
||||
* Data used when depth buffer is converted to uchar textures.
|
||||
*/
|
||||
ID3D12PipelineState *m_convertPSO;
|
||||
ID3D12RootSignature *m_convertRootSignature;
|
||||
void initConvertShader();
|
||||
ID3D12PipelineState *m_convert_pso;
|
||||
ID3D12RootSignature *m_convert_root_signature;
|
||||
void init_convert_shader();
|
||||
|
||||
resource_storage m_per_frame_storage[2];
|
||||
resource_storage &get_current_resource_storage();
|
||||
@@ -119,16 +119,21 @@ private:
|
||||
|
||||
rsx::render_targets m_rtts;
|
||||
|
||||
INT g_descriptor_stride_srv_cbv_uav;
|
||||
INT g_descriptor_stride_dsv;
|
||||
INT g_descriptor_stride_rtv;
|
||||
INT g_descriptor_stride_samplers;
|
||||
INT m_descriptor_stride_srv_cbv_uav;
|
||||
INT m_descriptor_stride_dsv;
|
||||
INT m_descriptor_stride_rtv;
|
||||
INT m_descriptor_stride_samplers;
|
||||
|
||||
// Used to fill unused texture slot
|
||||
ID3D12Resource *m_dummy_texture;
|
||||
|
||||
// Currently used shader resources / samplers descriptor
|
||||
std::array<std::tuple<ID3D12Resource*, D3D12_SHADER_RESOURCE_VIEW_DESC>, 16> m_current_shader_resources = {};
|
||||
std::array<D3D12_SAMPLER_DESC, 16> m_current_samplers = {};
|
||||
public:
|
||||
D3D12GSRender();
|
||||
virtual ~D3D12GSRender();
|
||||
|
||||
private:
|
||||
void init_d2d_structures();
|
||||
void release_d2d_structures();
|
||||
@@ -152,8 +157,6 @@ private:
|
||||
std::vector<D3D12_SHADER_RESOURCE_VIEW_DESC> upload_vertex_attributes(const std::vector<std::pair<u32, u32> > &vertex_ranges,
|
||||
gsl::not_null<ID3D12GraphicsCommandList*> command_list);
|
||||
|
||||
std::tuple<D3D12_VERTEX_BUFFER_VIEW, size_t> upload_inlined_vertex_array();
|
||||
|
||||
std::tuple<D3D12_INDEX_BUFFER_VIEW, size_t> generate_index_buffer_for_emulated_primitives_array(const std::vector<std::pair<u32, u32> > &vertex_ranges);
|
||||
|
||||
void upload_and_bind_scale_offset_matrix(size_t descriptor_index);
|
||||
@@ -165,7 +168,7 @@ private:
|
||||
* Create necessary resource view/sampler descriptors in the per frame storage struct.
|
||||
* If the count of enabled texture is below texture_count, fills with dummy texture and sampler.
|
||||
*/
|
||||
void upload_and_bind_textures(ID3D12GraphicsCommandList *command_list, size_t descriptor_index, size_t texture_count);
|
||||
void upload_and_bind_textures(ID3D12GraphicsCommandList *command_list, size_t texture_count);
|
||||
|
||||
/**
|
||||
* Creates render target if necessary.
|
||||
@@ -193,6 +196,8 @@ protected:
|
||||
virtual void end() override;
|
||||
virtual void flip(int buffer) override;
|
||||
|
||||
virtual bool on_access_violation(u32 address, bool is_writing) override;
|
||||
|
||||
virtual std::array<std::vector<gsl::byte>, 4> copy_render_targets_to_memory() override;
|
||||
virtual std::array<std::vector<gsl::byte>, 2> copy_depth_stencil_buffer_to_memory() override;
|
||||
virtual std::pair<std::string, std::string> get_programs() const override;
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
#include "D3D12MemoryHelpers.h"
|
||||
|
||||
|
||||
void data_cache::store_and_protect_data(u64 key, u32 start, size_t size, u8 format, size_t w, size_t h, size_t m, ComPtr<ID3D12Resource> data)
|
||||
void data_cache::store_and_protect_data(u64 key, u32 start, size_t size, u8 format, size_t w, size_t h, size_t d, size_t m, ComPtr<ID3D12Resource> data)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mut);
|
||||
m_address_to_data[key] = std::make_pair(texture_entry(format, w, h, m), data);
|
||||
m_address_to_data[key] = std::make_pair(texture_entry(format, w, h, d, m), data);
|
||||
protect_data(key, start, size);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ void resource_storage::init(ID3D12Device *device)
|
||||
CHECK_HRESULT(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, command_allocator.Get(), nullptr, IID_PPV_ARGS(command_list.GetAddressOf())));
|
||||
CHECK_HRESULT(command_list->Close());
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_DESC descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 10000, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
|
||||
D3D12_DESCRIPTOR_HEAP_DESC descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 50000, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
|
||||
CHECK_HRESULT(device->CreateDescriptorHeap(&descriptor_heap_desc, IID_PPV_ARGS(&descriptors_heap)));
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_DESC sampler_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER , 2048, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
|
||||
|
||||
@@ -47,6 +47,11 @@ class data_heap
|
||||
size_t m_put_pos; // Start of free space
|
||||
ComPtr<ID3D12Resource> m_heap;
|
||||
public:
|
||||
data_heap() = default;
|
||||
~data_heap() = default;
|
||||
data_heap(const data_heap&) = delete;
|
||||
data_heap(data_heap&&) = delete;
|
||||
|
||||
size_t m_get_pos; // End of free space
|
||||
|
||||
template <typename... arg_type>
|
||||
@@ -70,7 +75,7 @@ public:
|
||||
template<int Alignement>
|
||||
size_t alloc(size_t size)
|
||||
{
|
||||
if (!can_alloc<Alignement>(size)) LOG_ERROR (RSX, "Working buffer not big enough");
|
||||
if (!can_alloc<Alignement>(size)) throw EXCEPTION("Working buffer not big enough");
|
||||
size_t alloc_size = align(size, Alignement);
|
||||
size_t aligned_put_pos = align(m_put_pos, Alignement);
|
||||
if (aligned_put_pos + alloc_size < m_size)
|
||||
@@ -134,16 +139,17 @@ struct texture_entry
|
||||
size_t m_width;
|
||||
size_t m_height;
|
||||
size_t m_mipmap;
|
||||
size_t m_depth;
|
||||
|
||||
texture_entry() : m_format(0), m_width(0), m_height(0), m_is_dirty(true)
|
||||
texture_entry() : m_format(0), m_width(0), m_height(0), m_depth(0), m_is_dirty(true)
|
||||
{}
|
||||
|
||||
texture_entry(u8 f, size_t w, size_t h, size_t m) : m_format(f), m_width(w), m_height(h), m_is_dirty(false), m_mipmap(m)
|
||||
texture_entry(u8 f, size_t w, size_t h, size_t d, size_t m) : m_format(f), m_width(w), m_height(h), m_depth(d), m_is_dirty(false), m_mipmap(m)
|
||||
{}
|
||||
|
||||
bool operator==(const texture_entry &other)
|
||||
{
|
||||
return (m_format == other.m_format && m_width == other.m_width && m_height == other.m_height && m_mipmap == other.m_mipmap);
|
||||
return (m_format == other.m_format && m_width == other.m_width && m_height == other.m_height && m_mipmap == other.m_mipmap && m_depth == other.m_depth);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -163,7 +169,12 @@ private:
|
||||
std::unordered_map<u64, std::pair<texture_entry, ComPtr<ID3D12Resource>> > m_address_to_data; // Storage
|
||||
std::list <std::tuple<u64, u32, u32> > m_protected_ranges; // address, start of protected range, size of protected range
|
||||
public:
|
||||
void store_and_protect_data(u64 key, u32 start, size_t size, u8 format, size_t w, size_t h, size_t m, ComPtr<ID3D12Resource> data);
|
||||
data_cache() = default;
|
||||
~data_cache() = default;
|
||||
data_cache(const data_cache&) = delete;
|
||||
data_cache(data_cache&&) = delete;
|
||||
|
||||
void store_and_protect_data(u64 key, u32 start, size_t size, u8 format, size_t w, size_t h, size_t d, size_t m, ComPtr<ID3D12Resource> data);
|
||||
|
||||
/**
|
||||
* Make memory from start to start + size write protected.
|
||||
@@ -194,6 +205,11 @@ public:
|
||||
*/
|
||||
struct resource_storage
|
||||
{
|
||||
resource_storage() = default;
|
||||
~resource_storage() = default;
|
||||
resource_storage(const resource_storage&) = delete;
|
||||
resource_storage(resource_storage&&) = delete;
|
||||
|
||||
bool in_use; // False until command list has been populated at least once
|
||||
ComPtr<ID3D12Fence> frame_finished_fence;
|
||||
UINT64 fence_value;
|
||||
|
||||
@@ -152,21 +152,21 @@ void D3D12GSRender::release_d2d_structures()
|
||||
void D3D12GSRender::render_overlay()
|
||||
{
|
||||
D2D1_SIZE_F rtSize = g_d2d_render_targets[m_swap_chain->GetCurrentBackBufferIndex()]->GetSize();
|
||||
std::wstring duration = L"Draw duration : " + std::to_wstring(m_timers.m_draw_calls_duration) + L" us";
|
||||
float vtxIdxPercent = (float)m_timers.m_vertex_index_duration / (float)m_timers.m_draw_calls_duration;
|
||||
std::wstring vertexIndexDuration = L"Vtx/Idx upload : " + std::to_wstring(m_timers.m_vertex_index_duration) + L" us (" + std::to_wstring(100.f * vtxIdxPercent) + L" %)";
|
||||
std::wstring size = L"Upload size : " + std::to_wstring(m_timers.m_buffer_upload_size) + L" Bytes";
|
||||
float texPercent = (float)m_timers.m_texture_duration / (float)m_timers.m_draw_calls_duration;
|
||||
std::wstring texDuration = L"Textures : " + std::to_wstring(m_timers.m_texture_duration) + L" us (" + std::to_wstring(100.f * texPercent) + L" %)";
|
||||
float programPercent = (float)m_timers.m_program_load_duration / (float)m_timers.m_draw_calls_duration;
|
||||
std::wstring programDuration = L"Program : " + std::to_wstring(m_timers.m_program_load_duration) + L" us (" + std::to_wstring(100.f * programPercent) + L" %)";
|
||||
float constantsPercent = (float)m_timers.m_constants_duration / (float)m_timers.m_draw_calls_duration;
|
||||
std::wstring constantDuration = L"Constants : " + std::to_wstring(m_timers.m_constants_duration) + L" us (" + std::to_wstring(100.f * constantsPercent) + L" %)";
|
||||
float rttPercent = (float)m_timers.m_prepare_rtt_duration / (float)m_timers.m_draw_calls_duration;
|
||||
std::wstring rttDuration = L"RTT : " + std::to_wstring(m_timers.m_prepare_rtt_duration) + L" us (" + std::to_wstring(100.f * rttPercent) + L" %)";
|
||||
std::wstring flipDuration = L"Flip : " + std::to_wstring(m_timers.m_flip_duration) + L" us";
|
||||
std::wstring duration = L"Draw duration : " + std::to_wstring(m_timers.draw_calls_duration) + L" us";
|
||||
float vtxIdxPercent = (float)m_timers.vertex_index_duration / (float)m_timers.draw_calls_duration;
|
||||
std::wstring vertexIndexDuration = L"Vtx/Idx upload : " + std::to_wstring(m_timers.vertex_index_duration) + L" us (" + std::to_wstring(100.f * vtxIdxPercent) + L" %)";
|
||||
std::wstring size = L"Upload size : " + std::to_wstring(m_timers.buffer_upload_size) + L" Bytes";
|
||||
float texPercent = (float)m_timers.texture_duration / (float)m_timers.draw_calls_duration;
|
||||
std::wstring texDuration = L"Textures : " + std::to_wstring(m_timers.texture_duration) + L" us (" + std::to_wstring(100.f * texPercent) + L" %)";
|
||||
float programPercent = (float)m_timers.program_load_duration / (float)m_timers.draw_calls_duration;
|
||||
std::wstring programDuration = L"Program : " + std::to_wstring(m_timers.program_load_duration) + L" us (" + std::to_wstring(100.f * programPercent) + L" %)";
|
||||
float constantsPercent = (float)m_timers.constants_duration / (float)m_timers.draw_calls_duration;
|
||||
std::wstring constantDuration = L"Constants : " + std::to_wstring(m_timers.constants_duration) + L" us (" + std::to_wstring(100.f * constantsPercent) + L" %)";
|
||||
float rttPercent = (float)m_timers.prepare_rtt_duration / (float)m_timers.draw_calls_duration;
|
||||
std::wstring rttDuration = L"RTT : " + std::to_wstring(m_timers.prepare_rtt_duration) + L" us (" + std::to_wstring(100.f * rttPercent) + L" %)";
|
||||
std::wstring flipDuration = L"Flip : " + std::to_wstring(m_timers.flip_duration) + L" us";
|
||||
|
||||
std::wstring count = L"Draw count : " + std::to_wstring(m_timers.m_draw_calls_count);
|
||||
std::wstring count = L"Draw count : " + std::to_wstring(m_timers.draw_calls_count);
|
||||
draw_strings(rtSize, m_swap_chain->GetCurrentBackBufferIndex(),
|
||||
{
|
||||
duration,
|
||||
|
||||
@@ -38,72 +38,8 @@ void Shader::Compile(const std::string &code, SHADER_TYPE st)
|
||||
|
||||
void D3D12GSRender::load_program()
|
||||
{
|
||||
u32 transform_program_start = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START];
|
||||
vertex_program.data.reserve((512 - transform_program_start) * 4);
|
||||
|
||||
for (int i = transform_program_start; i < 512; ++i)
|
||||
{
|
||||
vertex_program.data.resize((i - transform_program_start) * 4 + 4);
|
||||
memcpy(vertex_program.data.data() + (i - transform_program_start) * 4, transform_program + i * 4, 4 * sizeof(u32));
|
||||
|
||||
D3 d3;
|
||||
d3.HEX = transform_program[i * 4 + 3];
|
||||
|
||||
if (d3.end)
|
||||
break;
|
||||
}
|
||||
vertex_program.output_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK];
|
||||
|
||||
u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK];
|
||||
u32 modulo_mask = rsx::method_registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION];
|
||||
vertex_program.rsx_vertex_inputs.clear();
|
||||
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
{
|
||||
bool enabled = !!(input_mask & (1 << index));
|
||||
if (!enabled)
|
||||
continue;
|
||||
|
||||
if (vertex_arrays_info[index].size > 0)
|
||||
{
|
||||
vertex_program.rsx_vertex_inputs.push_back(
|
||||
{
|
||||
index,
|
||||
vertex_arrays_info[index].size,
|
||||
vertex_arrays_info[index].frequency,
|
||||
!!((modulo_mask >> index) & 0x1),
|
||||
true
|
||||
}
|
||||
);
|
||||
}
|
||||
else if (register_vertex_info[index].size > 0)
|
||||
{
|
||||
vertex_program.rsx_vertex_inputs.push_back(
|
||||
{
|
||||
index,
|
||||
register_vertex_info[index].size,
|
||||
register_vertex_info[index].frequency,
|
||||
!!((modulo_mask >> index) & 0x1),
|
||||
false
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
|
||||
fragment_program.offset = shader_program & ~0x3;
|
||||
fragment_program.addr = rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1);
|
||||
fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL];
|
||||
fragment_program.texture_dimensions.clear();
|
||||
|
||||
for (u32 i = 0; i < rsx::limits::textures_count; ++i)
|
||||
{
|
||||
if (!textures[i].enabled())
|
||||
fragment_program.texture_dimensions.push_back(texture_dimension::texture_dimension_2d);
|
||||
else if (textures[i].cubemap())
|
||||
fragment_program.texture_dimensions.push_back(texture_dimension::texture_dimension_cubemap);
|
||||
else
|
||||
fragment_program.texture_dimensions.push_back(texture_dimension::texture_dimension_2d);
|
||||
}
|
||||
m_vertex_program = get_current_vertex_program();
|
||||
m_fragment_program = get_current_fragment_program();
|
||||
|
||||
D3D12PipelineProperties prop = {};
|
||||
prop.Topology = get_primitive_topology_type(draw_mode);
|
||||
@@ -198,19 +134,19 @@ void D3D12GSRender::load_program()
|
||||
prop.DepthStencilFormat = get_depth_stencil_surface_format(m_surface.depth_format);
|
||||
prop.RenderTargetsFormat = get_color_surface_format(m_surface.color_format);
|
||||
|
||||
switch (to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
|
||||
switch (rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
|
||||
{
|
||||
case Surface_target::surface_a:
|
||||
case Surface_target::surface_b:
|
||||
case rsx::surface_target::surface_a:
|
||||
case rsx::surface_target::surface_b:
|
||||
prop.numMRT = 1;
|
||||
break;
|
||||
case Surface_target::surfaces_a_b:
|
||||
case rsx::surface_target::surfaces_a_b:
|
||||
prop.numMRT = 2;
|
||||
break;
|
||||
case Surface_target::surfaces_a_b_c:
|
||||
case rsx::surface_target::surfaces_a_b_c:
|
||||
prop.numMRT = 3;
|
||||
break;
|
||||
case Surface_target::surfaces_a_b_c_d:
|
||||
case rsx::surface_target::surfaces_a_b_c_d:
|
||||
prop.numMRT = 4;
|
||||
break;
|
||||
default:
|
||||
@@ -259,7 +195,7 @@ void D3D12GSRender::load_program()
|
||||
D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF,
|
||||
};
|
||||
prop.Rasterization = CD3D12_RASTERIZER_DESC;
|
||||
if (rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE])
|
||||
if (!!rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE])
|
||||
{
|
||||
switch (rsx::method_registers[NV4097_SET_CULL_FACE])
|
||||
{
|
||||
@@ -289,23 +225,23 @@ void D3D12GSRender::load_program()
|
||||
|
||||
if (!!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE])
|
||||
{
|
||||
Index_array_type index_type = to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
if (index_type == Index_array_type::unsigned_32b)
|
||||
rsx::index_array_type index_type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
if (index_type == rsx::index_array_type::u32)
|
||||
{
|
||||
prop.CutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF;
|
||||
}
|
||||
if (index_type == Index_array_type::unsigned_16b)
|
||||
if (index_type == rsx::index_array_type::u16)
|
||||
{
|
||||
prop.CutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
m_current_pso = m_pso_cache.getGraphicPipelineState(vertex_program, fragment_program, prop, m_device.Get(), m_root_signatures);
|
||||
m_current_pso = m_pso_cache.getGraphicPipelineState(m_vertex_program, m_fragment_program, prop, m_device.Get(), m_root_signatures);
|
||||
return;
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> D3D12GSRender::get_programs() const
|
||||
{
|
||||
return std::make_pair(m_pso_cache.get_transform_program(vertex_program).content, m_pso_cache.get_shader_program(fragment_program).content);
|
||||
return std::make_pair(m_pso_cache.get_transform_program(m_vertex_program).content, m_pso_cache.get_shader_program(m_fragment_program).content);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -119,7 +119,7 @@ struct D3D12Traits
|
||||
{
|
||||
for (const ParamItem PI : PT.items)
|
||||
{
|
||||
if (PT.type == "sampler2D" || PT.type == "samplerCube")
|
||||
if (PT.type == "sampler1D" || PT.type == "sampler2D" || PT.type == "samplerCube" || PT.type == "sampler3D")
|
||||
{
|
||||
size_t texture_unit = atoi(PI.name.c_str() + 3);
|
||||
fragmentProgramData.m_textureCount = std::max(texture_unit + 1, fragmentProgramData.m_textureCount);
|
||||
@@ -130,7 +130,7 @@ struct D3D12Traits
|
||||
}
|
||||
}
|
||||
|
||||
fs::file(fs::get_config_dir() + "/hlsl/FragmentProgram" + std::to_string(ID) + ".hlsl", fom::rewrite).write(shader);
|
||||
fs::file(fs::get_config_dir() + "FragmentProgram" + std::to_string(ID) + ".hlsl", fom::rewrite).write(shader);
|
||||
fragmentProgramData.id = (u32)ID;
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ struct D3D12Traits
|
||||
std::string shaderCode = VS.Decompile();
|
||||
vertexProgramData.Compile(shaderCode, Shader::SHADER_TYPE::SHADER_TYPE_VERTEX);
|
||||
vertexProgramData.vertex_shader_input_count = RSXVP.rsx_vertex_inputs.size();
|
||||
fs::file(fs::get_config_dir() + "/hlsl/VertexProgram" + std::to_string(ID) + ".hlsl", fom::rewrite).write(shaderCode);
|
||||
fs::file(fs::get_config_dir() + "VertexProgram" + std::to_string(ID) + ".hlsl", fom::rewrite).write(shaderCode);
|
||||
vertexProgramData.id = (u32)ID;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,40 +15,40 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
u32 get_max_depth_value(Surface_depth_format format)
|
||||
u32 get_max_depth_value(rsx::surface_depth_format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Surface_depth_format::z16: return 0xFFFF;
|
||||
case Surface_depth_format::z24s8: return 0xFFFFFF;
|
||||
case rsx::surface_depth_format::z16: return 0xFFFF;
|
||||
case rsx::surface_depth_format::z24s8: return 0xFFFFFF;
|
||||
}
|
||||
throw EXCEPTION("Unknow depth format");
|
||||
}
|
||||
|
||||
UINT get_num_rtt(Surface_target color_target)
|
||||
UINT get_num_rtt(rsx::surface_target color_target)
|
||||
{
|
||||
switch (color_target)
|
||||
{
|
||||
case Surface_target::none: return 0;
|
||||
case Surface_target::surface_a:
|
||||
case Surface_target::surface_b: return 1;
|
||||
case Surface_target::surfaces_a_b: return 2;
|
||||
case Surface_target::surfaces_a_b_c: return 3;
|
||||
case Surface_target::surfaces_a_b_c_d: return 4;
|
||||
case rsx::surface_target::none: return 0;
|
||||
case rsx::surface_target::surface_a:
|
||||
case rsx::surface_target::surface_b: return 1;
|
||||
case rsx::surface_target::surfaces_a_b: return 2;
|
||||
case rsx::surface_target::surfaces_a_b_c: return 3;
|
||||
case rsx::surface_target::surfaces_a_b_c_d: return 4;
|
||||
}
|
||||
throw EXCEPTION("Wrong color_target (%d)", color_target);
|
||||
}
|
||||
|
||||
std::vector<u8> get_rtt_indexes(Surface_target color_target)
|
||||
std::vector<u8> get_rtt_indexes(rsx::surface_target color_target)
|
||||
{
|
||||
switch (color_target)
|
||||
{
|
||||
case Surface_target::none: return{};
|
||||
case Surface_target::surface_a: return{ 0 };
|
||||
case Surface_target::surface_b: return{ 1 };
|
||||
case Surface_target::surfaces_a_b: return{ 0, 1 };
|
||||
case Surface_target::surfaces_a_b_c: return{ 0, 1, 2 };
|
||||
case Surface_target::surfaces_a_b_c_d: return{ 0, 1, 2, 3 };
|
||||
case rsx::surface_target::none: return{};
|
||||
case rsx::surface_target::surface_a: return{ 0 };
|
||||
case rsx::surface_target::surface_b: return{ 1 };
|
||||
case rsx::surface_target::surfaces_a_b: return{ 0, 1 };
|
||||
case rsx::surface_target::surfaces_a_b_c: return{ 0, 1, 2 };
|
||||
case rsx::surface_target::surfaces_a_b_c_d: return{ 0, 1, 2, 3 };
|
||||
}
|
||||
throw EXCEPTION("Wrong color_target (%d)", color_target);
|
||||
}
|
||||
@@ -73,46 +73,46 @@ namespace
|
||||
return register_value & 0xff;
|
||||
}
|
||||
|
||||
size_t get_aligned_pitch(Surface_color_format format, u32 width)
|
||||
size_t get_aligned_pitch(rsx::surface_color_format format, u32 width)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Surface_color_format::b8: return align(width, 256);
|
||||
case Surface_color_format::g8b8:
|
||||
case Surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case Surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
case Surface_color_format::r5g6b5: return align(width * 2, 256);
|
||||
case Surface_color_format::a8b8g8r8:
|
||||
case Surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case Surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case Surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case Surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case Surface_color_format::x32:
|
||||
case Surface_color_format::a8r8g8b8: return align(width * 4, 256);
|
||||
case Surface_color_format::w16z16y16x16: return align(width * 8, 256);
|
||||
case Surface_color_format::w32z32y32x32: return align(width * 16, 256);
|
||||
case rsx::surface_color_format::b8: return align(width, 256);
|
||||
case rsx::surface_color_format::g8b8:
|
||||
case rsx::surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case rsx::surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
case rsx::surface_color_format::r5g6b5: return align(width * 2, 256);
|
||||
case rsx::surface_color_format::a8b8g8r8:
|
||||
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case rsx::surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case rsx::surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case rsx::surface_color_format::x32:
|
||||
case rsx::surface_color_format::a8r8g8b8: return align(width * 4, 256);
|
||||
case rsx::surface_color_format::w16z16y16x16: return align(width * 8, 256);
|
||||
case rsx::surface_color_format::w32z32y32x32: return align(width * 16, 256);
|
||||
}
|
||||
throw EXCEPTION("Unknow color surface format");
|
||||
}
|
||||
|
||||
size_t get_packed_pitch(Surface_color_format format, u32 width)
|
||||
size_t get_packed_pitch(rsx::surface_color_format format, u32 width)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Surface_color_format::b8: return width;
|
||||
case Surface_color_format::g8b8:
|
||||
case Surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case Surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
case Surface_color_format::r5g6b5: return width * 2;
|
||||
case Surface_color_format::a8b8g8r8:
|
||||
case Surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case Surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case Surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case Surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case Surface_color_format::x32:
|
||||
case Surface_color_format::a8r8g8b8: return width * 4;
|
||||
case Surface_color_format::w16z16y16x16: return width * 8;
|
||||
case Surface_color_format::w32z32y32x32: return width * 16;
|
||||
case rsx::surface_color_format::b8: return width;
|
||||
case rsx::surface_color_format::g8b8:
|
||||
case rsx::surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case rsx::surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
case rsx::surface_color_format::r5g6b5: return width * 2;
|
||||
case rsx::surface_color_format::a8b8g8r8:
|
||||
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case rsx::surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case rsx::surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case rsx::surface_color_format::x32:
|
||||
case rsx::surface_color_format::a8r8g8b8: return width * 4;
|
||||
case rsx::surface_color_format::w16z16y16x16: return width * 8;
|
||||
case rsx::surface_color_format::w32z32y32x32: return width * 16;
|
||||
}
|
||||
throw EXCEPTION("Unknow color surface format");
|
||||
}
|
||||
@@ -126,7 +126,7 @@ void D3D12GSRender::clear_surface(u32 arg)
|
||||
prepare_render_targets(get_current_resource_storage().command_list.Get());
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> rtt_duration_end = std::chrono::system_clock::now();
|
||||
m_timers.m_prepare_rtt_duration += std::chrono::duration_cast<std::chrono::microseconds>(rtt_duration_end - rtt_duration_start).count();
|
||||
m_timers.prepare_rtt_duration += std::chrono::duration_cast<std::chrono::microseconds>(rtt_duration_end - rtt_duration_start).count();
|
||||
|
||||
if (arg & 0x1 || arg & 0x2)
|
||||
{
|
||||
@@ -148,16 +148,16 @@ void D3D12GSRender::clear_surface(u32 arg)
|
||||
if (arg & 0xF0)
|
||||
{
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.current_rtts_handle);
|
||||
size_t rtt_index = get_num_rtt(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]));
|
||||
size_t rtt_index = get_num_rtt(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]));
|
||||
get_current_resource_storage().render_targets_descriptors_heap_index += rtt_index;
|
||||
for (unsigned i = 0; i < rtt_index; i++)
|
||||
get_current_resource_storage().command_list->ClearRenderTargetView(handle.Offset(i, g_descriptor_stride_rtv), get_clear_color(rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]).data(),
|
||||
get_current_resource_storage().command_list->ClearRenderTargetView(handle.Offset(i, m_descriptor_stride_rtv), get_clear_color(rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]).data(),
|
||||
1, &get_scissor(rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL], rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL]));
|
||||
}
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> end_duration = std::chrono::system_clock::now();
|
||||
m_timers.m_draw_calls_duration += std::chrono::duration_cast<std::chrono::microseconds>(end_duration - start_duration).count();
|
||||
m_timers.m_draw_calls_count++;
|
||||
m_timers.draw_calls_duration += std::chrono::duration_cast<std::chrono::microseconds>(end_duration - start_duration).count();
|
||||
m_timers.draw_calls_count++;
|
||||
|
||||
if (rpcs3::config.rsx.d3d12.debug_output.value())
|
||||
{
|
||||
@@ -185,7 +185,7 @@ void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlis
|
||||
m_rtts.prepare_render_target(copycmdlist,
|
||||
rsx::method_registers[NV4097_SET_SURFACE_FORMAT],
|
||||
rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL], rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL],
|
||||
to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]),
|
||||
rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]),
|
||||
get_color_surface_addresses(), get_zeta_surface_address(),
|
||||
m_device.Get(), clear_color, 1.f, 0);
|
||||
|
||||
@@ -196,14 +196,14 @@ void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlis
|
||||
rtt_view_desc.Format = dxgi_format;
|
||||
|
||||
m_rtts.current_rtts_handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().render_targets_descriptors_heap->GetCPUDescriptorHandleForHeapStart())
|
||||
.Offset((INT)get_current_resource_storage().render_targets_descriptors_heap_index * g_descriptor_stride_rtv);
|
||||
.Offset((INT)get_current_resource_storage().render_targets_descriptors_heap_index * m_descriptor_stride_rtv);
|
||||
size_t rtt_index = 0;
|
||||
for (u8 i : get_rtt_indexes(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])))
|
||||
for (u8 i : get_rtt_indexes(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])))
|
||||
{
|
||||
if (std::get<1>(m_rtts.m_bound_render_targets[i]) == nullptr)
|
||||
continue;
|
||||
m_device->CreateRenderTargetView(std::get<1>(m_rtts.m_bound_render_targets[i]), &rtt_view_desc,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.current_rtts_handle).Offset((INT)rtt_index * g_descriptor_stride_rtv));
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.current_rtts_handle).Offset((INT)rtt_index * m_descriptor_stride_rtv));
|
||||
rtt_index++;
|
||||
}
|
||||
get_current_resource_storage().render_targets_descriptors_heap_index += rtt_index;
|
||||
@@ -211,7 +211,7 @@ void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlis
|
||||
if (std::get<1>(m_rtts.m_bound_depth_stencil) == nullptr)
|
||||
return;
|
||||
m_rtts.current_ds_handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart())
|
||||
.Offset((INT)get_current_resource_storage().depth_stencil_descriptor_heap_index * g_descriptor_stride_dsv);
|
||||
.Offset((INT)get_current_resource_storage().depth_stencil_descriptor_heap_index * m_descriptor_stride_dsv);
|
||||
get_current_resource_storage().depth_stencil_descriptor_heap_index += 1;
|
||||
D3D12_DEPTH_STENCIL_VIEW_DESC depth_stencil_view_desc = {};
|
||||
depth_stencil_view_desc.Format = get_depth_stencil_surface_format(m_surface.depth_format);
|
||||
@@ -221,7 +221,7 @@ void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlis
|
||||
|
||||
void D3D12GSRender::set_rtt_and_ds(ID3D12GraphicsCommandList *command_list)
|
||||
{
|
||||
UINT num_rtt = get_num_rtt(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]));
|
||||
UINT num_rtt = get_num_rtt(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]));
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE* ds_handle = (std::get<1>(m_rtts.m_bound_depth_stencil) != nullptr) ? &m_rtts.current_ds_handle : nullptr;
|
||||
command_list->OMSetRenderTargets((UINT)num_rtt, &m_rtts.current_rtts_handle, true, ds_handle);
|
||||
}
|
||||
@@ -242,7 +242,7 @@ namespace
|
||||
ID3D12GraphicsCommandList * command_list,
|
||||
data_heap &readback_heap,
|
||||
ID3D12Resource * color_surface,
|
||||
Surface_color_format color_surface_format
|
||||
rsx::surface_color_format color_surface_format
|
||||
)
|
||||
{
|
||||
int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16;
|
||||
@@ -362,13 +362,13 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
||||
uav_desc.Format = DXGI_FORMAT_R8_UNORM;
|
||||
uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
|
||||
m_device->CreateUnorderedAccessView(depth_format_conversion_buffer.Get(), nullptr, &uav_desc,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(descriptor_heap->GetCPUDescriptorHandleForHeapStart()).Offset(1, g_descriptor_stride_srv_cbv_uav));
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(descriptor_heap->GetCPUDescriptorHandleForHeapStart()).Offset(1, m_descriptor_stride_srv_cbv_uav));
|
||||
|
||||
// Convert
|
||||
get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(std::get<1>(m_rtts.m_bound_depth_stencil), D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ));
|
||||
|
||||
get_current_resource_storage().command_list->SetPipelineState(m_convertPSO);
|
||||
get_current_resource_storage().command_list->SetComputeRootSignature(m_convertRootSignature);
|
||||
get_current_resource_storage().command_list->SetPipelineState(m_convert_pso);
|
||||
get_current_resource_storage().command_list->SetComputeRootSignature(m_convert_root_signature);
|
||||
get_current_resource_storage().command_list->SetDescriptorHeaps(1, descriptor_heap.GetAddressOf());
|
||||
get_current_resource_storage().command_list->SetComputeRootDescriptorTable(0, descriptor_heap->GetGPUDescriptorHandleForHeapStart());
|
||||
get_current_resource_storage().command_list->Dispatch(clip_w / 8, clip_h / 8, 1);
|
||||
@@ -391,7 +391,7 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
||||
size_t color_buffer_offset_in_heap[4];
|
||||
if (rpcs3::state.config.rsx.opengl.write_color_buffers)
|
||||
{
|
||||
for (u8 i : get_rtt_indexes(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])))
|
||||
for (u8 i : get_rtt_indexes(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])))
|
||||
{
|
||||
if (!address_color[i])
|
||||
continue;
|
||||
@@ -443,7 +443,7 @@ void D3D12GSRender::copy_render_target_to_dma_location()
|
||||
vm::base(address_color[3]),
|
||||
};
|
||||
|
||||
for (u8 i : get_rtt_indexes(to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])))
|
||||
for (u8 i : get_rtt_indexes(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])))
|
||||
{
|
||||
if (!address_color[i])
|
||||
continue;
|
||||
|
||||
@@ -21,10 +21,10 @@ struct render_target_traits
|
||||
static
|
||||
ComPtr<ID3D12Resource> create_new_surface(
|
||||
u32 address,
|
||||
Surface_color_format surface_color_format, size_t width, size_t height,
|
||||
surface_color_format color_format, size_t width, size_t height,
|
||||
gsl::not_null<ID3D12Device*> device, const std::array<float, 4> &clear_color, float, u8)
|
||||
{
|
||||
DXGI_FORMAT dxgi_format = get_color_surface_format(surface_color_format);
|
||||
DXGI_FORMAT dxgi_format = get_color_surface_format(color_format);
|
||||
ComPtr<ID3D12Resource> rtt;
|
||||
LOG_WARNING(RSX, "Creating RTT");
|
||||
|
||||
@@ -69,7 +69,7 @@ struct render_target_traits
|
||||
static
|
||||
ComPtr<ID3D12Resource> create_new_surface(
|
||||
u32 address,
|
||||
Surface_depth_format surfaceDepthFormat, size_t width, size_t height,
|
||||
surface_depth_format surfaceDepthFormat, size_t width, size_t height,
|
||||
gsl::not_null<ID3D12Device*> device, const std::array<float, 4>& , float clear_depth, u8 clear_stencil)
|
||||
{
|
||||
D3D12_CLEAR_VALUE clear_depth_value = {};
|
||||
@@ -113,14 +113,14 @@ struct render_target_traits
|
||||
|
||||
|
||||
static
|
||||
bool rtt_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, Surface_color_format surface_color_format, size_t width, size_t height)
|
||||
bool rtt_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, surface_color_format surface_color_format, size_t width, size_t height)
|
||||
{
|
||||
DXGI_FORMAT dxgi_format = get_color_surface_format(surface_color_format);
|
||||
return rtt->GetDesc().Format == dxgi_format && rtt->GetDesc().Width == width && rtt->GetDesc().Height == height;
|
||||
}
|
||||
|
||||
static
|
||||
bool ds_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, Surface_depth_format surface_depth_stencil_format, size_t width, size_t height)
|
||||
bool ds_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, surface_depth_format surface_depth_stencil_format, size_t width, size_t height)
|
||||
{
|
||||
//TODO: Check format
|
||||
return rtt->GetDesc().Width == width && rtt->GetDesc().Height == height;
|
||||
@@ -129,7 +129,7 @@ struct render_target_traits
|
||||
static
|
||||
std::tuple<size_t, size_t, size_t, ComPtr<ID3D12Fence>, HANDLE> issue_download_command(
|
||||
gsl::not_null<ID3D12Resource*> rtt,
|
||||
Surface_color_format color_format, size_t width, size_t height,
|
||||
surface_color_format color_format, size_t width, size_t height,
|
||||
gsl::not_null<ID3D12Device*> device, gsl::not_null<ID3D12CommandQueue*> command_queue, data_heap &readback_heap, resource_storage &res_store
|
||||
)
|
||||
{
|
||||
@@ -162,12 +162,12 @@ struct render_target_traits
|
||||
static
|
||||
std::tuple<size_t, size_t, size_t, ComPtr<ID3D12Fence>, HANDLE> issue_depth_download_command(
|
||||
gsl::not_null<ID3D12Resource*> ds,
|
||||
Surface_depth_format depth_format, size_t width, size_t height,
|
||||
surface_depth_format depth_format, size_t width, size_t height,
|
||||
gsl::not_null<ID3D12Device*> device, gsl::not_null<ID3D12CommandQueue*> command_queue, data_heap &readback_heap, resource_storage &res_store
|
||||
)
|
||||
{
|
||||
ID3D12GraphicsCommandList* command_list = res_store.command_list.Get();
|
||||
DXGI_FORMAT dxgi_format = (depth_format == Surface_depth_format::z24s8) ? DXGI_FORMAT_R32_TYPELESS : DXGI_FORMAT_R16_TYPELESS;
|
||||
DXGI_FORMAT dxgi_format = (depth_format == surface_depth_format::z24s8) ? DXGI_FORMAT_R32_TYPELESS : DXGI_FORMAT_R16_TYPELESS;
|
||||
|
||||
size_t row_pitch = align(width * 4, 256);
|
||||
size_t buffer_size = row_pitch * height;
|
||||
|
||||
@@ -40,6 +40,31 @@ D3D12_SAMPLER_DESC get_sampler_desc(const rsx::texture &texture)
|
||||
return samplerDesc;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
CD3DX12_RESOURCE_DESC get_texture_description(const rsx::texture &texture)
|
||||
{
|
||||
const u8 format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
DXGI_FORMAT dxgi_format = get_texture_format(format);
|
||||
|
||||
if (texture.dimension() == 1) // 1D texture or cubemap
|
||||
{
|
||||
return CD3DX12_RESOURCE_DESC::Tex1D(dxgi_format, texture.width(), 1, texture.mipmap());
|
||||
}
|
||||
else if (texture.dimension() == 2) // 2D texture or cubemap
|
||||
{
|
||||
// if (texture.depth() < 2);
|
||||
size_t depth = (texture.cubemap()) ? 6 : 1;
|
||||
return CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, texture.width(), texture.height(), (UINT)depth, texture.mipmap());
|
||||
}
|
||||
else if (texture.dimension() == 3) // 3d texture
|
||||
{
|
||||
return CD3DX12_RESOURCE_DESC::Tex3D(dxgi_format, texture.width(), texture.height(), texture.depth(), texture.mipmap());
|
||||
}
|
||||
throw EXCEPTION("Unknow texture dimension");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a texture residing in default heap and generate uploads commands in commandList,
|
||||
@@ -51,14 +76,6 @@ ComPtr<ID3D12Resource> upload_single_texture(
|
||||
ID3D12GraphicsCommandList *command_list,
|
||||
data_heap &texture_buffer_heap)
|
||||
{
|
||||
size_t w = texture.width(), h = texture.height();
|
||||
size_t depth = texture.depth();
|
||||
if (depth == 0) depth = 1;
|
||||
if (texture.cubemap()) depth *= 6;
|
||||
|
||||
const u8 format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
DXGI_FORMAT dxgi_format = get_texture_format(format);
|
||||
|
||||
size_t buffer_size = get_placed_texture_storage_size(texture, 256);
|
||||
size_t heap_offset = texture_buffer_heap.alloc<D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
|
||||
|
||||
@@ -70,17 +87,19 @@ ComPtr<ID3D12Resource> upload_single_texture(
|
||||
CHECK_HRESULT(device->CreateCommittedResource(
|
||||
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, (UINT)w, (UINT)h, (UINT)depth, texture.mipmap()),
|
||||
&get_texture_description(texture),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(result.GetAddressOf())
|
||||
));
|
||||
|
||||
const u8 format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
DXGI_FORMAT dxgi_format = get_texture_format(format);
|
||||
size_t mip_level = 0;
|
||||
for (const MipmapLevelInfo mli : mipInfos)
|
||||
{
|
||||
command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(result.Get(), (UINT)mip_level), 0, 0, 0,
|
||||
&CD3DX12_TEXTURE_COPY_LOCATION(texture_buffer_heap.get_heap(), { heap_offset + mli.offset, { dxgi_format, (UINT)mli.width, (UINT)mli.height, 1, (UINT)mli.rowPitch } }), nullptr);
|
||||
&CD3DX12_TEXTURE_COPY_LOCATION(texture_buffer_heap.get_heap(), { heap_offset + mli.offset, { dxgi_format, (UINT)mli.width, (UINT)mli.height, (UINT)mli.depth, (UINT)mli.rowPitch } }), nullptr);
|
||||
mip_level++;
|
||||
}
|
||||
|
||||
@@ -114,20 +133,52 @@ void update_existing_texture(
|
||||
for (const MipmapLevelInfo mli : mipInfos)
|
||||
{
|
||||
command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(existing_texture, (UINT)miplevel), 0, 0, 0,
|
||||
&CD3DX12_TEXTURE_COPY_LOCATION(texture_buffer_heap.get_heap(), { heap_offset + mli.offset,{ dxgi_format, (UINT)mli.width, (UINT)mli.height, 1, (UINT)mli.rowPitch } }), nullptr);
|
||||
&CD3DX12_TEXTURE_COPY_LOCATION(texture_buffer_heap.get_heap(), { heap_offset + mli.offset,{ dxgi_format, (UINT)mli.width, (UINT)mli.height, (UINT)mli.depth, (UINT)mli.rowPitch } }), nullptr);
|
||||
miplevel++;
|
||||
}
|
||||
|
||||
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(existing_texture, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_GENERIC_READ));
|
||||
}
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC get_srv_descriptor_with_dimensions(const rsx::texture &tex)
|
||||
{
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = {};
|
||||
if (tex.dimension() == 1)
|
||||
{
|
||||
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
|
||||
shared_resource_view_desc.Texture1D.MipLevels = tex.mipmap();
|
||||
return shared_resource_view_desc;
|
||||
}
|
||||
if (tex.dimension() == 2)
|
||||
{
|
||||
if (tex.cubemap())
|
||||
{
|
||||
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
|
||||
shared_resource_view_desc.TextureCube.MipLevels = tex.mipmap();
|
||||
return shared_resource_view_desc;
|
||||
}
|
||||
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
shared_resource_view_desc.Texture2D.MipLevels = tex.mipmap();
|
||||
return shared_resource_view_desc;
|
||||
}
|
||||
if (tex.dimension() == 3)
|
||||
{
|
||||
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
|
||||
shared_resource_view_desc.Texture3D.MipLevels = tex.mipmap();
|
||||
return shared_resource_view_desc;
|
||||
}
|
||||
throw EXCEPTION("Wrong texture dimension %d", tex.dimension());
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_list, size_t descriptor_index, size_t texture_count)
|
||||
void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_list, size_t texture_count)
|
||||
{
|
||||
size_t used_texture = 0;
|
||||
|
||||
for (u32 i = 0; i < rsx::limits::textures_count; ++i)
|
||||
for (u32 i = 0; i < 16; ++i)
|
||||
{
|
||||
if (!m_textures_dirty[i])
|
||||
continue;
|
||||
m_textures_dirty[i] = false;
|
||||
|
||||
if (!textures[i].enabled())
|
||||
{
|
||||
// Now fill remaining texture slots with dummy texture/sampler
|
||||
@@ -141,21 +192,14 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0);
|
||||
m_device->CreateShaderResourceView(m_dummy_texture, &shader_resource_view_desc,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
|
||||
.Offset((INT)descriptor_index + (INT)used_texture, g_descriptor_stride_srv_cbv_uav)
|
||||
);
|
||||
m_current_shader_resources[i] = std::make_tuple(m_dummy_texture, shader_resource_view_desc);
|
||||
|
||||
D3D12_SAMPLER_DESC sampler_desc = {};
|
||||
sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
|
||||
sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||
sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||
sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||
m_device->CreateSampler(&sampler_desc,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().sampler_descriptor_heap[get_current_resource_storage().sampler_descriptors_heap_index]->GetCPUDescriptorHandleForHeapStart())
|
||||
.Offset((INT)get_current_resource_storage().current_sampler_index + (INT)used_texture, g_descriptor_stride_samplers)
|
||||
);
|
||||
used_texture++;
|
||||
m_current_samplers[i] = sampler_desc;
|
||||
continue;
|
||||
}
|
||||
size_t w = textures[i].width(), h = textures[i].height();
|
||||
@@ -178,7 +222,7 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_
|
||||
{
|
||||
is_depth_stencil_texture = true;
|
||||
}
|
||||
else if (cached_texture != nullptr && (cached_texture->first == texture_entry(format, w, h, textures[i].mipmap())))
|
||||
else if (cached_texture != nullptr && (cached_texture->first == texture_entry(format, w, h, textures[i].depth(), textures[i].mipmap())))
|
||||
{
|
||||
if (cached_texture->first.m_is_dirty)
|
||||
{
|
||||
@@ -195,20 +239,10 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_
|
||||
std::wstring name = L"texture_@" + std::to_wstring(texaddr);
|
||||
tex->SetName(name.c_str());
|
||||
vram_texture = tex.Get();
|
||||
m_texture_cache.store_and_protect_data(texaddr, texaddr, get_texture_size(textures[i]), format, w, h, textures[i].mipmap(), tex);
|
||||
m_texture_cache.store_and_protect_data(texaddr, texaddr, get_texture_size(textures[i]), format, w, h, textures[i].depth(), textures[i].mipmap(), tex);
|
||||
}
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = {};
|
||||
if (textures[i].cubemap())
|
||||
{
|
||||
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
|
||||
shared_resource_view_desc.TextureCube.MipLevels = textures[i].mipmap();
|
||||
}
|
||||
else
|
||||
{
|
||||
shared_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
shared_resource_view_desc.Texture2D.MipLevels = textures[i].mipmap();
|
||||
}
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = get_srv_descriptor_with_dimensions(textures[i]);
|
||||
shared_resource_view_desc.Format = get_texture_format(format);
|
||||
|
||||
switch (format)
|
||||
@@ -318,9 +352,7 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_
|
||||
break;
|
||||
}
|
||||
|
||||
m_device->CreateShaderResourceView(vram_texture, &shared_resource_view_desc,
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().descriptors_heap->GetCPUDescriptorHandleForHeapStart())
|
||||
.Offset((UINT)descriptor_index + (UINT)used_texture, g_descriptor_stride_srv_cbv_uav));
|
||||
m_current_shader_resources[i] = std::make_tuple(vram_texture, shared_resource_view_desc);
|
||||
|
||||
if (get_current_resource_storage().current_sampler_index + 16 > 2048)
|
||||
{
|
||||
@@ -334,13 +366,7 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_
|
||||
};
|
||||
command_list->SetDescriptorHeaps(2, descriptors);
|
||||
}
|
||||
m_device->CreateSampler(&get_sampler_desc(textures[i]),
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().sampler_descriptor_heap[get_current_resource_storage().sampler_descriptors_heap_index]->GetCPUDescriptorHandleForHeapStart())
|
||||
.Offset((UINT)get_current_resource_storage().current_sampler_index + (UINT)used_texture, g_descriptor_stride_samplers));
|
||||
|
||||
used_texture++;
|
||||
m_current_samplers[i] = get_sampler_desc(textures[i]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -47,7 +47,7 @@ std::pair<ID3DBlob *, ID3DBlob *> compileF32toU8CS()
|
||||
}
|
||||
|
||||
|
||||
void D3D12GSRender::Shader::Init(ID3D12Device *device, ID3D12CommandQueue *gfxcommandqueue)
|
||||
void D3D12GSRender::shader::init(ID3D12Device *device, ID3D12CommandQueue *gfx_command_queue)
|
||||
{
|
||||
const char *fsCode = STRINGIFY(
|
||||
Texture2D InputTexture : register(t0); \n
|
||||
@@ -143,21 +143,21 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device, ID3D12CommandQueue *gfxco
|
||||
Microsoft::WRL::ComPtr<ID3DBlob> rootSignatureBlob;
|
||||
|
||||
CHECK_HRESULT(wrapD3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &rootSignatureBlob, &errorBlob));
|
||||
CHECK_HRESULT(device->CreateRootSignature(0, rootSignatureBlob->GetBufferPointer(), rootSignatureBlob->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)));
|
||||
CHECK_HRESULT(device->CreateRootSignature(0, rootSignatureBlob->GetBufferPointer(), rootSignatureBlob->GetBufferSize(), IID_PPV_ARGS(&root_signature)));
|
||||
|
||||
psoDesc.pRootSignature = m_rootSignature;
|
||||
psoDesc.pRootSignature = root_signature;
|
||||
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
psoDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
|
||||
|
||||
CHECK_HRESULT(device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_PSO)));
|
||||
CHECK_HRESULT(device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pso)));
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_DESC textureHeapDesc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV , 2, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
|
||||
CHECK_HRESULT(
|
||||
device->CreateDescriptorHeap(&textureHeapDesc, IID_PPV_ARGS(&m_textureDescriptorHeap))
|
||||
device->CreateDescriptorHeap(&textureHeapDesc, IID_PPV_ARGS(&texture_descriptor_heap))
|
||||
);
|
||||
D3D12_DESCRIPTOR_HEAP_DESC samplerHeapDesc = { D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER , 2, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
|
||||
CHECK_HRESULT(
|
||||
device->CreateDescriptorHeap(&samplerHeapDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap))
|
||||
device->CreateDescriptorHeap(&samplerHeapDesc, IID_PPV_ARGS(&sampler_descriptor_heap))
|
||||
);
|
||||
|
||||
ComPtr<ID3D12Fence> fence;
|
||||
@@ -197,37 +197,37 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device, ID3D12CommandQueue *gfxco
|
||||
&CD3DX12_RESOURCE_DESC::Buffer(16 * sizeof(float)),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&m_vertexBuffer)
|
||||
IID_PPV_ARGS(&vertex_buffer)
|
||||
));
|
||||
|
||||
D3D12_SUBRESOURCE_DATA vertexData = { reinterpret_cast<BYTE*>(quadVertex), 16 * sizeof(float), 1 };
|
||||
|
||||
UpdateSubresources(cmdList.Get(), m_vertexBuffer, intermediateBuffer.Get(), 0, 0, 1, &vertexData);
|
||||
cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));
|
||||
UpdateSubresources(cmdList.Get(), vertex_buffer, intermediateBuffer.Get(), 0, 0, 1, &vertexData);
|
||||
cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(vertex_buffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));
|
||||
CHECK_HRESULT(cmdList->Close());
|
||||
|
||||
gfxcommandqueue->ExecuteCommandLists(1, CommandListCast(cmdList.GetAddressOf()));
|
||||
gfx_command_queue->ExecuteCommandLists(1, CommandListCast(cmdList.GetAddressOf()));
|
||||
|
||||
// Now wait until upload has completed
|
||||
gfxcommandqueue->Signal(fence.Get(), 1);
|
||||
gfx_command_queue->Signal(fence.Get(), 1);
|
||||
WaitForSingleObjectEx(handle, INFINITE, FALSE);
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
void D3D12GSRender::initConvertShader()
|
||||
void D3D12GSRender::init_convert_shader()
|
||||
{
|
||||
const auto &p = compileF32toU8CS();
|
||||
CHECK_HRESULT(
|
||||
m_device->CreateRootSignature(0, p.second->GetBufferPointer(), p.second->GetBufferSize(), IID_PPV_ARGS(&m_convertRootSignature))
|
||||
m_device->CreateRootSignature(0, p.second->GetBufferPointer(), p.second->GetBufferSize(), IID_PPV_ARGS(&m_convert_root_signature))
|
||||
);
|
||||
|
||||
D3D12_COMPUTE_PIPELINE_STATE_DESC computePipelineStateDesc = {};
|
||||
computePipelineStateDesc.CS.BytecodeLength = p.first->GetBufferSize();
|
||||
computePipelineStateDesc.CS.pShaderBytecode = p.first->GetBufferPointer();
|
||||
computePipelineStateDesc.pRootSignature = m_convertRootSignature;
|
||||
computePipelineStateDesc.pRootSignature = m_convert_root_signature;
|
||||
|
||||
CHECK_HRESULT(
|
||||
m_device->CreateComputePipelineState(&computePipelineStateDesc, IID_PPV_ARGS(&m_convertPSO))
|
||||
m_device->CreateComputePipelineState(&computePipelineStateDesc, IID_PPV_ARGS(&m_convert_pso))
|
||||
);
|
||||
|
||||
p.first->Release();
|
||||
|
||||
@@ -33,22 +33,6 @@ void D3D12VertexProgramDecompiler::insertHeader(std::stringstream &OS)
|
||||
OS << " float4x4 scaleOffsetMat;" << std::endl;
|
||||
OS << " int isAlphaTested;" << std::endl;
|
||||
OS << " float alphaRef;" << std::endl;
|
||||
OS << " int tex0_is_unorm;" << std::endl;
|
||||
OS << " int tex1_is_unorm;" << std::endl;
|
||||
OS << " int tex2_is_unorm;" << std::endl;
|
||||
OS << " int tex3_is_unorm;" << std::endl;
|
||||
OS << " int tex4_is_unorm;" << std::endl;
|
||||
OS << " int tex5_is_unorm;" << std::endl;
|
||||
OS << " int tex6_is_unorm;" << std::endl;
|
||||
OS << " int tex7_is_unorm;" << std::endl;
|
||||
OS << " int tex8_is_unorm;" << std::endl;
|
||||
OS << " int tex9_is_unorm;" << std::endl;
|
||||
OS << " int tex10_is_unorm;" << std::endl;
|
||||
OS << " int tex11_is_unorm;" << std::endl;
|
||||
OS << " int tex12_is_unorm;" << std::endl;
|
||||
OS << " int tex13_is_unorm;" << std::endl;
|
||||
OS << " int tex14_is_unorm;" << std::endl;
|
||||
OS << " int tex15_is_unorm;" << std::endl;
|
||||
OS << "};" << std::endl;
|
||||
}
|
||||
|
||||
@@ -60,7 +44,7 @@ namespace
|
||||
{
|
||||
if (static_cast<size_t>(real_input.location) != std::get<0>(attribute))
|
||||
continue;
|
||||
OS << "Texture1D<float4> " << std::get<1>(attribute) << "_buffer : register(t" << reg++ << ");\n";
|
||||
OS << "Buffer<float4> " << std::get<1>(attribute) << "_buffer : register(t" << reg++ << ");\n";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -170,20 +154,20 @@ namespace
|
||||
continue;
|
||||
if (!real_input.is_array)
|
||||
{
|
||||
OS << " float4 " << PI.name << " = " << PI.name << "_buffer.Load(0);\n";
|
||||
OS << " float4 " << PI.name << " = " << PI.name << "_buffer[0];\n";
|
||||
return;
|
||||
}
|
||||
if (real_input.frequency > 1)
|
||||
{
|
||||
if (real_input.is_modulo)
|
||||
{
|
||||
OS << " float4 " << PI.name << " = " << PI.name << "_buffer.Load(vertex_id % " << real_input.frequency << ");\n";
|
||||
OS << " float4 " << PI.name << " = " << PI.name << "_buffer[vertex_id % " << real_input.frequency << "];\n";
|
||||
return;
|
||||
}
|
||||
OS << " float4 " << PI.name << " = " << PI.name << "_buffer.Load(vertex_id / " << real_input.frequency << ");\n";
|
||||
OS << " float4 " << PI.name << " = " << PI.name << "_buffer[vertex_id / " << real_input.frequency << "];\n";
|
||||
return;
|
||||
}
|
||||
OS << " float4 " << PI.name << " = " << PI.name << "_buffer.Load(vertex_id);\n";
|
||||
OS << " float4 " << PI.name << " = " << PI.name << "_buffer[vertex_id];\n";
|
||||
return;
|
||||
}
|
||||
OS << " float4 " << PI.name << " = float4(0., 0., 0., 1.);\n";
|
||||
@@ -192,6 +176,8 @@ namespace
|
||||
|
||||
void D3D12VertexProgramDecompiler::insertMainStart(std::stringstream & OS)
|
||||
{
|
||||
insert_d3d12_legacy_function(OS);
|
||||
|
||||
OS << "PixelInput main(uint vertex_id : SV_VertexID)" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
|
||||
|
||||
+176
-106
@@ -719,49 +719,93 @@ namespace
|
||||
};
|
||||
}
|
||||
|
||||
Vertex_base_type to_vertex_base_type(u8 in)
|
||||
rsx::vertex_base_type rsx::to_vertex_base_type(u8 in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case 1: return Vertex_base_type::s1;
|
||||
case 2: return Vertex_base_type::f;
|
||||
case 3: return Vertex_base_type::sf;
|
||||
case 4: return Vertex_base_type::ub;
|
||||
case 5: return Vertex_base_type::s32k;
|
||||
case 6: return Vertex_base_type::cmp;
|
||||
case 7: return Vertex_base_type::ub256;
|
||||
case 1: return rsx::vertex_base_type::s1;
|
||||
case 2: return rsx::vertex_base_type::f;
|
||||
case 3: return rsx::vertex_base_type::sf;
|
||||
case 4: return rsx::vertex_base_type::ub;
|
||||
case 5: return rsx::vertex_base_type::s32k;
|
||||
case 6: return rsx::vertex_base_type::cmp;
|
||||
case 7: return rsx::vertex_base_type::ub256;
|
||||
}
|
||||
throw new EXCEPTION("Unknow vertex base type %d", in);
|
||||
}
|
||||
|
||||
Index_array_type to_index_array_type(u8 in)
|
||||
rsx::index_array_type rsx::to_index_array_type(u8 in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case 0: return Index_array_type::unsigned_32b;
|
||||
case 1: return Index_array_type::unsigned_16b;
|
||||
case 0: return rsx::index_array_type::u32;
|
||||
case 1: return rsx::index_array_type::u16;
|
||||
}
|
||||
throw new EXCEPTION("Unknown index array type %d", in);
|
||||
}
|
||||
|
||||
Primitive_type to_primitive_type(u8 in)
|
||||
rsx::primitive_type rsx::to_primitive_type(u8 in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case 1: return Primitive_type::points;
|
||||
case 2: return Primitive_type::lines;
|
||||
case 3: return Primitive_type::line_loop;
|
||||
case 4: return Primitive_type::line_strip;
|
||||
case 5: return Primitive_type::triangles;
|
||||
case 6: return Primitive_type::triangle_strip;
|
||||
case 7: return Primitive_type::triangle_fan;
|
||||
case 8: return Primitive_type::quads;
|
||||
case 9: return Primitive_type::quad_strip;
|
||||
case 10: return Primitive_type::polygon;
|
||||
case 1: return rsx::primitive_type::points;
|
||||
case 2: return rsx::primitive_type::lines;
|
||||
case 3: return rsx::primitive_type::line_loop;
|
||||
case 4: return rsx::primitive_type::line_strip;
|
||||
case 5: return rsx::primitive_type::triangles;
|
||||
case 6: return rsx::primitive_type::triangle_strip;
|
||||
case 7: return rsx::primitive_type::triangle_fan;
|
||||
case 8: return rsx::primitive_type::quads;
|
||||
case 9: return rsx::primitive_type::quad_strip;
|
||||
case 10: return rsx::primitive_type::polygon;
|
||||
}
|
||||
throw new EXCEPTION("Unknow primitive type %d", in);
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_GCM_WINDOW_ORIGIN_TOP = 0,
|
||||
CELL_GCM_WINDOW_ORIGIN_BOTTOM = 1,
|
||||
CELL_GCM_WINDOW_PIXEL_CENTER_HALF = 0,
|
||||
CELL_GCM_WINDOW_PIXEL_CENTER_INTEGER = 1,
|
||||
};
|
||||
|
||||
rsx::window_origin rsx::to_window_origin(u8 in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case CELL_GCM_WINDOW_ORIGIN_TOP: return rsx::window_origin::top;
|
||||
case CELL_GCM_WINDOW_ORIGIN_BOTTOM: return rsx::window_origin::bottom;
|
||||
}
|
||||
throw EXCEPTION("Unknow window origin modifier %x", in);
|
||||
}
|
||||
|
||||
rsx::window_pixel_center rsx::to_window_pixel_center(u8 in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case CELL_GCM_WINDOW_PIXEL_CENTER_HALF: return rsx::window_pixel_center::half;
|
||||
case CELL_GCM_WINDOW_PIXEL_CENTER_INTEGER: return rsx::window_pixel_center::integer;
|
||||
}
|
||||
throw EXCEPTION("Unknow window pixel center %x", in);
|
||||
}
|
||||
|
||||
rsx::comparaison_function rsx::to_comparaison_function(u16 in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case CELL_GCM_NEVER: return rsx::comparaison_function::never;
|
||||
case CELL_GCM_LESS: return rsx::comparaison_function::less;
|
||||
case CELL_GCM_EQUAL: return rsx::comparaison_function::equal;
|
||||
case CELL_GCM_LEQUAL: return rsx::comparaison_function::less_or_equal;
|
||||
case CELL_GCM_GREATER: return rsx::comparaison_function::greater;
|
||||
case CELL_GCM_NOTEQUAL: return rsx::comparaison_function::not_equal;
|
||||
case CELL_GCM_GEQUAL: return rsx::comparaison_function::greater_or_equal;
|
||||
case CELL_GCM_ALWAYS: return rsx::comparaison_function::always;
|
||||
}
|
||||
throw EXCEPTION("Wrong comparaison function %x", in);
|
||||
}
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -801,26 +845,26 @@ enum
|
||||
|
||||
};
|
||||
|
||||
Surface_target to_surface_target(u8 in)
|
||||
rsx::surface_target rsx::to_surface_target(u8 in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case CELL_GCM_SURFACE_TARGET_NONE: return Surface_target::none;
|
||||
case CELL_GCM_SURFACE_TARGET_0: return Surface_target::surface_a;
|
||||
case CELL_GCM_SURFACE_TARGET_1: return Surface_target::surface_b;
|
||||
case CELL_GCM_SURFACE_TARGET_MRT1: return Surface_target::surfaces_a_b;
|
||||
case CELL_GCM_SURFACE_TARGET_MRT2: return Surface_target::surfaces_a_b_c;
|
||||
case CELL_GCM_SURFACE_TARGET_MRT3: return Surface_target::surfaces_a_b_c_d;
|
||||
case CELL_GCM_SURFACE_TARGET_NONE: return rsx::surface_target::none;
|
||||
case CELL_GCM_SURFACE_TARGET_0: return rsx::surface_target::surface_a;
|
||||
case CELL_GCM_SURFACE_TARGET_1: return rsx::surface_target::surface_b;
|
||||
case CELL_GCM_SURFACE_TARGET_MRT1: return rsx::surface_target::surfaces_a_b;
|
||||
case CELL_GCM_SURFACE_TARGET_MRT2: return rsx::surface_target::surfaces_a_b_c;
|
||||
case CELL_GCM_SURFACE_TARGET_MRT3: return rsx::surface_target::surfaces_a_b_c_d;
|
||||
}
|
||||
throw EXCEPTION("Unknow surface target %x", in);
|
||||
}
|
||||
|
||||
Surface_depth_format to_surface_depth_format(u8 in)
|
||||
rsx::surface_depth_format rsx::to_surface_depth_format(u8 in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case CELL_GCM_SURFACE_Z16: return Surface_depth_format::z16;
|
||||
case CELL_GCM_SURFACE_Z24S8: return Surface_depth_format::z24s8;
|
||||
case CELL_GCM_SURFACE_Z16: return rsx::surface_depth_format::z16;
|
||||
case CELL_GCM_SURFACE_Z24S8: return rsx::surface_depth_format::z24s8;
|
||||
}
|
||||
throw EXCEPTION("Unknow surface depth format %x", in);
|
||||
}
|
||||
@@ -836,36 +880,36 @@ std::string rsx::get_method_name(const u32 id)
|
||||
return fmt::format("unknown/illegal method [0x%08x]", id);
|
||||
}
|
||||
|
||||
Surface_antialiasing to_surface_antialiasing(u8 in)
|
||||
rsx::surface_antialiasing rsx::to_surface_antialiasing(u8 in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case CELL_GCM_SURFACE_CENTER_1: return Surface_antialiasing::center_1_sample;
|
||||
case CELL_GCM_SURFACE_DIAGONAL_CENTERED_2: return Surface_antialiasing::diagonal_centered_2_samples;
|
||||
case CELL_GCM_SURFACE_SQUARE_CENTERED_4: return Surface_antialiasing::square_centered_4_samples;
|
||||
case CELL_GCM_SURFACE_SQUARE_ROTATED_4: return Surface_antialiasing::square_rotated_4_samples;
|
||||
case CELL_GCM_SURFACE_CENTER_1: return rsx::surface_antialiasing::center_1_sample;
|
||||
case CELL_GCM_SURFACE_DIAGONAL_CENTERED_2: return rsx::surface_antialiasing::diagonal_centered_2_samples;
|
||||
case CELL_GCM_SURFACE_SQUARE_CENTERED_4: return rsx::surface_antialiasing::square_centered_4_samples;
|
||||
case CELL_GCM_SURFACE_SQUARE_ROTATED_4: return rsx::surface_antialiasing::square_rotated_4_samples;
|
||||
}
|
||||
throw EXCEPTION("unknow surface antialiasing format %x", in);
|
||||
}
|
||||
|
||||
Surface_color_format to_surface_color_format(u8 in)
|
||||
rsx::surface_color_format rsx::to_surface_color_format(u8 in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5: return Surface_color_format::x1r5g5b5_z1r5g5b5;
|
||||
case CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5: return Surface_color_format::x1r5g5b5_o1r5g5b5;
|
||||
case CELL_GCM_SURFACE_R5G6B5: return Surface_color_format::r5g6b5;
|
||||
case CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8: return Surface_color_format::x8r8g8b8_z8r8g8b8;
|
||||
case CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8: return Surface_color_format::x8r8g8b8_o8r8g8b8;
|
||||
case CELL_GCM_SURFACE_A8R8G8B8: return Surface_color_format::a8r8g8b8;
|
||||
case CELL_GCM_SURFACE_B8: return Surface_color_format::b8;
|
||||
case CELL_GCM_SURFACE_G8B8: return Surface_color_format::g8b8;
|
||||
case CELL_GCM_SURFACE_F_W16Z16Y16X16: return Surface_color_format::w16z16y16x16;
|
||||
case CELL_GCM_SURFACE_F_W32Z32Y32X32: return Surface_color_format::w32z32y32x32;
|
||||
case CELL_GCM_SURFACE_F_X32: return Surface_color_format::x32;
|
||||
case CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8: return Surface_color_format::x8b8g8r8_z8b8g8r8;
|
||||
case CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8: return Surface_color_format::x8b8g8r8_o8b8g8r8;
|
||||
case CELL_GCM_SURFACE_A8B8G8R8: return Surface_color_format::a8b8g8r8;
|
||||
case CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5: return rsx::surface_color_format::x1r5g5b5_z1r5g5b5;
|
||||
case CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5: return rsx::surface_color_format::x1r5g5b5_o1r5g5b5;
|
||||
case CELL_GCM_SURFACE_R5G6B5: return rsx::surface_color_format::r5g6b5;
|
||||
case CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8: return rsx::surface_color_format::x8r8g8b8_z8r8g8b8;
|
||||
case CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8: return rsx::surface_color_format::x8r8g8b8_o8r8g8b8;
|
||||
case CELL_GCM_SURFACE_A8R8G8B8: return rsx::surface_color_format::a8r8g8b8;
|
||||
case CELL_GCM_SURFACE_B8: return rsx::surface_color_format::b8;
|
||||
case CELL_GCM_SURFACE_G8B8: return rsx::surface_color_format::g8b8;
|
||||
case CELL_GCM_SURFACE_F_W16Z16Y16X16: return rsx::surface_color_format::w16z16y16x16;
|
||||
case CELL_GCM_SURFACE_F_W32Z32Y32X32: return rsx::surface_color_format::w32z32y32x32;
|
||||
case CELL_GCM_SURFACE_F_X32: return rsx::surface_color_format::x32;
|
||||
case CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8: return rsx::surface_color_format::x8b8g8r8_z8b8g8r8;
|
||||
case CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8: return rsx::surface_color_format::x8b8g8r8_o8b8g8r8;
|
||||
case CELL_GCM_SURFACE_A8B8G8R8: return rsx::surface_color_format::a8b8g8r8;
|
||||
}
|
||||
throw EXCEPTION("unknow surface color format %x", in);
|
||||
}
|
||||
@@ -953,18 +997,18 @@ namespace
|
||||
|
||||
std::string get_primitive_mode(u8 draw_mode)
|
||||
{
|
||||
switch (to_primitive_type(draw_mode))
|
||||
switch (rsx::to_primitive_type(draw_mode))
|
||||
{
|
||||
case Primitive_type::points: return "Points";
|
||||
case Primitive_type::lines: return "Lines";
|
||||
case Primitive_type::line_loop: return "Line_loop";
|
||||
case Primitive_type::line_strip: return "Line_strip";
|
||||
case Primitive_type::triangles: return "Triangles";
|
||||
case Primitive_type::triangle_strip: return "Triangle_strip";
|
||||
case Primitive_type::triangle_fan: return "Triangle_fan";
|
||||
case Primitive_type::quads: return "Quads";
|
||||
case Primitive_type::quad_strip: return "Quad_strip";
|
||||
case Primitive_type::polygon: return "Polygon";
|
||||
case rsx::primitive_type::points: return "Points";
|
||||
case rsx::primitive_type::lines: return "Lines";
|
||||
case rsx::primitive_type::line_loop: return "Line_loop";
|
||||
case rsx::primitive_type::line_strip: return "Line_strip";
|
||||
case rsx::primitive_type::triangles: return "Triangles";
|
||||
case rsx::primitive_type::triangle_strip: return "Triangle_strip";
|
||||
case rsx::primitive_type::triangle_fan: return "Triangle_fan";
|
||||
case rsx::primitive_type::quads: return "Quads";
|
||||
case rsx::primitive_type::quad_strip: return "Quad_strip";
|
||||
case rsx::primitive_type::polygon: return "Polygon";
|
||||
}
|
||||
return "Error";
|
||||
}
|
||||
@@ -989,58 +1033,58 @@ namespace
|
||||
|
||||
std::string depth_stencil_surface_format(u32 format)
|
||||
{
|
||||
switch (to_surface_depth_format(format))
|
||||
switch (rsx::to_surface_depth_format(format))
|
||||
{
|
||||
case Surface_depth_format::z16: return "CELL_GCM_SURFACE_Z16";
|
||||
case Surface_depth_format::z24s8: return "CELL_GCM_SURFACE_Z24S8";
|
||||
case rsx::surface_depth_format::z16: return "CELL_GCM_SURFACE_Z16";
|
||||
case rsx::surface_depth_format::z24s8: return "CELL_GCM_SURFACE_Z24S8";
|
||||
}
|
||||
return "Error";
|
||||
}
|
||||
|
||||
std::string surface_antialiasing(u8 format)
|
||||
{
|
||||
switch (to_surface_antialiasing(format))
|
||||
switch (rsx::to_surface_antialiasing(format))
|
||||
{
|
||||
case Surface_antialiasing::center_1_sample: "1 sample centered";
|
||||
case Surface_antialiasing::diagonal_centered_2_samples: return "2 samples diagonal centered";
|
||||
case Surface_antialiasing::square_centered_4_samples: return "4 samples square centered";
|
||||
case Surface_antialiasing::square_rotated_4_samples: return "4 samples diagonal rotated";
|
||||
case rsx::surface_antialiasing::center_1_sample: return "1 sample centered";
|
||||
case rsx::surface_antialiasing::diagonal_centered_2_samples: return "2 samples diagonal centered";
|
||||
case rsx::surface_antialiasing::square_centered_4_samples: return "4 samples square centered";
|
||||
case rsx::surface_antialiasing::square_rotated_4_samples: return "4 samples diagonal rotated";
|
||||
}
|
||||
return "Error";
|
||||
}
|
||||
|
||||
std::string color_surface_format(u32 format)
|
||||
std::string surface_color_format(u32 format)
|
||||
{
|
||||
switch (to_surface_color_format(format))
|
||||
switch (rsx::to_surface_color_format(format))
|
||||
{
|
||||
case Surface_color_format::x1r5g5b5_z1r5g5b5: return "CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5";
|
||||
case Surface_color_format::x1r5g5b5_o1r5g5b5: return "CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5";
|
||||
case Surface_color_format::r5g6b5 : return "CELL_GCM_SURFACE_R5G6B5";
|
||||
case Surface_color_format::x8r8g8b8_z8r8g8b8: return "CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8";
|
||||
case Surface_color_format::x8r8g8b8_o8r8g8b8: return "CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8";
|
||||
case Surface_color_format::a8r8g8b8: return "CELL_GCM_SURFACE_A8R8G8B8";
|
||||
case Surface_color_format::b8: return "CELL_GCM_SURFACE_B8";
|
||||
case Surface_color_format::g8b8: return "CELL_GCM_SURFACE_G8B8";
|
||||
case Surface_color_format::w16z16y16x16: return "CELL_GCM_SURFACE_F_W16Z16Y16X16";
|
||||
case Surface_color_format::w32z32y32x32: return "CELL_GCM_SURFACE_F_W32Z32Y32X32";
|
||||
case Surface_color_format::x32: return "CELL_GCM_SURFACE_F_X32";
|
||||
case Surface_color_format::x8b8g8r8_z8b8g8r8: return "CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8";
|
||||
case Surface_color_format::x8b8g8r8_o8b8g8r8: return "CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8";
|
||||
case Surface_color_format::a8b8g8r8: return "CELL_GCM_SURFACE_A8B8G8R8";
|
||||
case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: return "CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5";
|
||||
case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: return "CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5";
|
||||
case rsx::surface_color_format::r5g6b5 : return "CELL_GCM_SURFACE_R5G6B5";
|
||||
case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: return "CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8";
|
||||
case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: return "CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8";
|
||||
case rsx::surface_color_format::a8r8g8b8: return "CELL_GCM_SURFACE_A8R8G8B8";
|
||||
case rsx::surface_color_format::b8: return "CELL_GCM_SURFACE_B8";
|
||||
case rsx::surface_color_format::g8b8: return "CELL_GCM_SURFACE_G8B8";
|
||||
case rsx::surface_color_format::w16z16y16x16: return "CELL_GCM_SURFACE_F_W16Z16Y16X16";
|
||||
case rsx::surface_color_format::w32z32y32x32: return "CELL_GCM_SURFACE_F_W32Z32Y32X32";
|
||||
case rsx::surface_color_format::x32: return "CELL_GCM_SURFACE_F_X32";
|
||||
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: return "CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8";
|
||||
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: return "CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8";
|
||||
case rsx::surface_color_format::a8b8g8r8: return "CELL_GCM_SURFACE_A8B8G8R8";
|
||||
}
|
||||
return "Error";
|
||||
}
|
||||
|
||||
std::string surface_target(u32 target)
|
||||
{
|
||||
switch (to_surface_target(target))
|
||||
switch (rsx::to_surface_target(target))
|
||||
{
|
||||
case Surface_target::none: return "none";
|
||||
case Surface_target::surface_a: return "surface A";
|
||||
case Surface_target::surface_b: return "surface B";
|
||||
case Surface_target::surfaces_a_b: return "surfaces A and B";
|
||||
case Surface_target::surfaces_a_b_c: return "surfaces A, B and C";
|
||||
case Surface_target::surfaces_a_b_c_d: return "surfaces A,B, C and D";
|
||||
case rsx::surface_target::none: return "none";
|
||||
case rsx::surface_target::surface_a: return "surface A";
|
||||
case rsx::surface_target::surface_b: return "surface B";
|
||||
case rsx::surface_target::surfaces_a_b: return "surfaces A and B";
|
||||
case rsx::surface_target::surfaces_a_b_c: return "surfaces A, B and C";
|
||||
case rsx::surface_target::surfaces_a_b_c_d: return "surfaces A,B, C and D";
|
||||
}
|
||||
return "Error";
|
||||
}
|
||||
@@ -1078,15 +1122,15 @@ namespace
|
||||
|
||||
std::string get_vertex_attribute_format(u8 type)
|
||||
{
|
||||
switch (to_vertex_base_type(type))
|
||||
switch (rsx::to_vertex_base_type(type))
|
||||
{
|
||||
case Vertex_base_type::s1: return "Short";
|
||||
case Vertex_base_type::f: return "Float";
|
||||
case Vertex_base_type::sf: return "Half float";
|
||||
case Vertex_base_type::ub: return "Unsigned byte";
|
||||
case Vertex_base_type::s32k: return "Signed int";
|
||||
case Vertex_base_type::cmp: return "CMP";
|
||||
case Vertex_base_type::ub256: return "UB256";
|
||||
case rsx::vertex_base_type::s1: return "Short";
|
||||
case rsx::vertex_base_type::f: return "Float";
|
||||
case rsx::vertex_base_type::sf: return "Half float";
|
||||
case rsx::vertex_base_type::ub: return "Unsigned byte";
|
||||
case rsx::vertex_base_type::s32k: return "Signed int";
|
||||
case rsx::vertex_base_type::cmp: return "CMP";
|
||||
case rsx::vertex_base_type::ub256: return "UB256";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1104,10 +1148,10 @@ namespace
|
||||
|
||||
std::string index_type(u16 arg)
|
||||
{
|
||||
switch (to_index_array_type(arg))
|
||||
switch (rsx::to_index_array_type(arg))
|
||||
{
|
||||
case Index_array_type::unsigned_16b: return "unsigned short";
|
||||
case Index_array_type::unsigned_32b: return "unsigned int";
|
||||
case rsx::index_array_type::u16: return "unsigned short";
|
||||
case rsx::index_array_type::u32: return "unsigned int";
|
||||
}
|
||||
return "Error";
|
||||
}
|
||||
@@ -1378,6 +1422,31 @@ namespace
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string origin_mode(u32 origin)
|
||||
{
|
||||
switch (rsx::to_window_origin(origin))
|
||||
{
|
||||
case rsx::window_origin::bottom: return "bottom";
|
||||
case rsx::window_origin::top: return "top";
|
||||
}
|
||||
throw EXCEPTION("Wrong origin mode");
|
||||
}
|
||||
|
||||
std::string pixel_center_mode(u32 in)
|
||||
{
|
||||
switch (rsx::to_window_pixel_center(in))
|
||||
{
|
||||
case rsx::window_pixel_center::half: return "half";
|
||||
case rsx::window_pixel_center::integer: return "integer";
|
||||
}
|
||||
throw EXCEPTION("Wrong origin mode");
|
||||
}
|
||||
|
||||
std::string shader_window(u32 arg)
|
||||
{
|
||||
return "Viewport: height = " + std::to_string(arg & 0xFFF) + " origin = " + origin_mode((arg >> 12) & 0xF) + " pixel center = " + pixel_center_mode((arg >> 16) & 0xF);
|
||||
}
|
||||
|
||||
#define OPCODE_RANGE_1(opcode, increment, index, printing_function) \
|
||||
{ (opcode) + (index) * (increment), [](u32 arg) -> std::string { return (printing_function)((index), arg); } },
|
||||
|
||||
@@ -1443,7 +1512,7 @@ namespace
|
||||
{ NV4097_SET_SURFACE_PITCH_Z, [](u32 arg) -> std::string { return "Surface Zeta: Pitch = " + std::to_string(arg); } },
|
||||
{ NV4097_SET_SURFACE_ZETA_OFFSET, [](u32 arg) -> std::string { return "Surface Zeta: Offset = " + ptr_to_string(arg); } },
|
||||
{ NV4097_SET_CONTEXT_DMA_ZETA, [](u32 arg) -> std::string { return "Surface Zeta: DMA mode = " + dma_mode(arg);} },
|
||||
{ NV4097_SET_SURFACE_FORMAT, [](u32 arg) -> std::string { return "Surface: Color format = " + color_surface_format(arg & 0x1F) + " DepthStencil format = " + depth_stencil_surface_format((arg >> 5) & 0x7) + " Anti aliasing =" + surface_antialiasing((arg >> 12) & 0x7); } },
|
||||
{ NV4097_SET_SURFACE_FORMAT, [](u32 arg) -> std::string { return "Surface: Color format = " + surface_color_format(arg & 0x1F) + " DepthStencil format = " + depth_stencil_surface_format((arg >> 5) & 0x7) + " Anti aliasing =" + surface_antialiasing((arg >> 12) & 0x7); } },
|
||||
{ NV4097_SET_SURFACE_CLIP_HORIZONTAL, [](u32 arg) -> std::string { return "Surface: clip x = " + std::to_string(arg & 0xFFFF) + " width = " + std::to_string(arg >> 16); } },
|
||||
{ NV4097_SET_SURFACE_CLIP_VERTICAL, [](u32 arg) -> std::string { return "Surface: clip y = " + std::to_string(arg & 0xFFFF) + " height = " + std::to_string(arg >> 16); } },
|
||||
{ NV4097_SET_SURFACE_COLOR_TARGET, [](u32 arg) -> std::string { return "Surface: Targets " + surface_target(arg); } },
|
||||
@@ -1476,6 +1545,7 @@ namespace
|
||||
{ NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK, vertex_output_mask },
|
||||
{ NV4097_SET_SHADER_CONTROL, shader_control },
|
||||
{ NV4097_SET_ANTI_ALIASING_CONTROL, anti_aliasing_control },
|
||||
{ NV4097_SET_SHADER_WINDOW, shader_window },
|
||||
{ NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, [](u32 arg) -> std::string { return "Vertex array 0: " + unpack_vertex_format(arg); } },
|
||||
{ NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 1, [](u32 arg) -> std::string { return "Vertex array 1: " + unpack_vertex_format(arg); } },
|
||||
{ NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 2, [](u32 arg) -> std::string { return "Vertex array 2: " + unpack_vertex_format(arg); } },
|
||||
|
||||
+105
-78
@@ -23,92 +23,125 @@ enum
|
||||
CELL_GCM_DISPLAY_FREQUENCY_DISABLE = 3,
|
||||
};
|
||||
|
||||
enum class Vertex_base_type : u8
|
||||
namespace rsx
|
||||
{
|
||||
s1, ///< signed byte
|
||||
f, ///< float
|
||||
sf, ///< half float
|
||||
ub, ///< unsigned byte
|
||||
s32k, ///< signed 32bits int
|
||||
cmp, ///< compressed aka X11G11Z10 and always 1. W.
|
||||
ub256,
|
||||
};
|
||||
enum class vertex_base_type : u8
|
||||
{
|
||||
s1, ///< signed byte
|
||||
f, ///< float
|
||||
sf, ///< half float
|
||||
ub, ///< unsigned byte
|
||||
s32k, ///< signed 32bits int
|
||||
cmp, ///< compressed aka X11G11Z10 and always 1. W.
|
||||
ub256,
|
||||
};
|
||||
|
||||
Vertex_base_type to_vertex_base_type(u8 in);
|
||||
vertex_base_type to_vertex_base_type(u8 in);
|
||||
|
||||
enum class Index_array_type : u8
|
||||
{
|
||||
unsigned_32b,
|
||||
unsigned_16b,
|
||||
};
|
||||
enum class index_array_type : u8
|
||||
{
|
||||
u32,
|
||||
u16,
|
||||
};
|
||||
|
||||
Index_array_type to_index_array_type(u8 in);
|
||||
index_array_type to_index_array_type(u8 in);
|
||||
|
||||
enum class Primitive_type : u8
|
||||
{
|
||||
points,
|
||||
lines,
|
||||
line_loop, // line strip with last end being joined with first end.
|
||||
line_strip,
|
||||
triangles,
|
||||
triangle_strip,
|
||||
triangle_fan, // like strip except that every triangle share the first vertex and one instead of 2 from previous triangle.
|
||||
quads,
|
||||
quad_strip,
|
||||
polygon, // convex polygon
|
||||
};
|
||||
enum class primitive_type : u8
|
||||
{
|
||||
points,
|
||||
lines,
|
||||
line_loop, // line strip with last end being joined with first end.
|
||||
line_strip,
|
||||
triangles,
|
||||
triangle_strip,
|
||||
triangle_fan, // like strip except that every triangle share the first vertex and one instead of 2 from previous triangle.
|
||||
quads,
|
||||
quad_strip,
|
||||
polygon, // convex polygon
|
||||
};
|
||||
|
||||
Primitive_type to_primitive_type(u8 in);
|
||||
primitive_type to_primitive_type(u8 in);
|
||||
|
||||
enum class Surface_target : u8
|
||||
{
|
||||
none,
|
||||
surface_a,
|
||||
surface_b,
|
||||
surfaces_a_b,
|
||||
surfaces_a_b_c,
|
||||
surfaces_a_b_c_d,
|
||||
};
|
||||
enum class surface_target : u8
|
||||
{
|
||||
none,
|
||||
surface_a,
|
||||
surface_b,
|
||||
surfaces_a_b,
|
||||
surfaces_a_b_c,
|
||||
surfaces_a_b_c_d,
|
||||
};
|
||||
|
||||
Surface_target to_surface_target(u8 in);
|
||||
surface_target to_surface_target(u8 in);
|
||||
|
||||
enum class Surface_depth_format : u8
|
||||
{
|
||||
z16, // unsigned 16 bits depth
|
||||
z24s8, // unsigned 24 bits depth + 8 bits stencil
|
||||
};
|
||||
enum class surface_depth_format : u8
|
||||
{
|
||||
z16, // unsigned 16 bits depth
|
||||
z24s8, // unsigned 24 bits depth + 8 bits stencil
|
||||
};
|
||||
|
||||
Surface_depth_format to_surface_depth_format(u8 in);
|
||||
surface_depth_format to_surface_depth_format(u8 in);
|
||||
|
||||
enum class Surface_antialiasing : u8
|
||||
{
|
||||
center_1_sample,
|
||||
diagonal_centered_2_samples,
|
||||
square_centered_4_samples,
|
||||
square_rotated_4_samples,
|
||||
};
|
||||
enum class surface_antialiasing : u8
|
||||
{
|
||||
center_1_sample,
|
||||
diagonal_centered_2_samples,
|
||||
square_centered_4_samples,
|
||||
square_rotated_4_samples,
|
||||
};
|
||||
|
||||
Surface_antialiasing to_surface_antialiasing(u8 in);
|
||||
surface_antialiasing to_surface_antialiasing(u8 in);
|
||||
|
||||
enum class Surface_color_format : u8
|
||||
{
|
||||
x1r5g5b5_z1r5g5b5,
|
||||
x1r5g5b5_o1r5g5b5,
|
||||
r5g6b5,
|
||||
x8r8g8b8_z8r8g8b8,
|
||||
x8r8g8b8_o8r8g8b8,
|
||||
a8r8g8b8,
|
||||
b8,
|
||||
g8b8,
|
||||
w16z16y16x16,
|
||||
w32z32y32x32,
|
||||
x32,
|
||||
x8b8g8r8_z8b8g8r8,
|
||||
x8b8g8r8_o8b8g8r8,
|
||||
a8b8g8r8,
|
||||
};
|
||||
enum class surface_color_format : u8
|
||||
{
|
||||
x1r5g5b5_z1r5g5b5,
|
||||
x1r5g5b5_o1r5g5b5,
|
||||
r5g6b5,
|
||||
x8r8g8b8_z8r8g8b8,
|
||||
x8r8g8b8_o8r8g8b8,
|
||||
a8r8g8b8,
|
||||
b8,
|
||||
g8b8,
|
||||
w16z16y16x16,
|
||||
w32z32y32x32,
|
||||
x32,
|
||||
x8b8g8r8_z8b8g8r8,
|
||||
x8b8g8r8_o8b8g8r8,
|
||||
a8b8g8r8,
|
||||
};
|
||||
|
||||
Surface_color_format to_surface_color_format(u8 in);
|
||||
surface_color_format to_surface_color_format(u8 in);
|
||||
|
||||
enum class window_origin : u8
|
||||
{
|
||||
top,
|
||||
bottom
|
||||
};
|
||||
|
||||
window_origin to_window_origin(u8 in);
|
||||
|
||||
enum class window_pixel_center : u8
|
||||
{
|
||||
half,
|
||||
integer
|
||||
};
|
||||
|
||||
window_pixel_center to_window_pixel_center(u8 in);
|
||||
|
||||
enum class comparaison_function : u8
|
||||
{
|
||||
never,
|
||||
less,
|
||||
equal,
|
||||
less_or_equal,
|
||||
greater,
|
||||
not_equal,
|
||||
greater_or_equal,
|
||||
always
|
||||
};
|
||||
|
||||
comparaison_function to_comparaison_function(u16 in);
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -478,12 +511,6 @@ enum
|
||||
CELL_GCM_TRUE = 1,
|
||||
CELL_GCM_FALSE = 0,
|
||||
|
||||
CELL_GCM_WINDOW_ORIGIN_TOP = 0,
|
||||
CELL_GCM_WINDOW_ORIGIN_BOTTOM = 1,
|
||||
|
||||
CELL_GCM_WINDOW_PIXEL_CENTER_HALF = 0,
|
||||
CELL_GCM_WINDOW_PIXEL_CENTER_INTEGER = 1,
|
||||
|
||||
CELL_GCM_USER_CLIP_PLANE_DISABLE = 0,
|
||||
CELL_GCM_USER_CLIP_PLANE_ENABLE_LT = 1,
|
||||
CELL_GCM_USER_CLIP_PLANE_ENABLE_GE = 2,
|
||||
|
||||
@@ -40,17 +40,23 @@ std::string getFunctionImpl(FUNCTION f)
|
||||
return "vec4(1., 1., 1., 1.)";
|
||||
case FUNCTION::FUNCTION_FRACT:
|
||||
return "fract($0)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE:
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D:
|
||||
return "texture($t, $0.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ:
|
||||
return "textureProj($t, $0.x, $1.x)"; // Note: $1.x is bias
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD:
|
||||
return "textureLod($t, $0.x, $1)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D:
|
||||
return "texture($t, $0.xy)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ:
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ:
|
||||
return "textureProj($t, $0.xyz, $1.x)"; // Note: $1.x is bias
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_LOD:
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD:
|
||||
return "textureLod($t, $0.xy, $1)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE:
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE:
|
||||
return "texture($t, $0.xyz)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ:
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ:
|
||||
return "textureProj($t, $0.xyzw, $1.x)"; // Note: $1.x is bias
|
||||
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_LOD:
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD:
|
||||
return "textureLod($t, $0.xyz, $1)";
|
||||
case FUNCTION::FUNCTION_DFDX:
|
||||
return "dFdx($0)";
|
||||
@@ -78,3 +84,39 @@ std::string compareFunctionImpl(COMPARE f, const std::string &Op0, const std::st
|
||||
}
|
||||
throw EXCEPTION("Unknow compare function");
|
||||
}
|
||||
|
||||
void insert_glsl_legacy_function(std::ostream& OS)
|
||||
{
|
||||
OS << "vec4 divsq_legacy(vec4 num, vec4 denum)\n";
|
||||
OS << "{\n";
|
||||
OS << " return num / sqrt(max(denum.xxxx, 1.E-10));\n";
|
||||
OS << "}\n";
|
||||
|
||||
OS << "vec4 rcp_legacy(vec4 denum)\n";
|
||||
OS << "{\n";
|
||||
OS << " return 1. / denum;\n";
|
||||
OS << "}\n";
|
||||
|
||||
OS << "vec4 rsq_legacy(vec4 val)\n";
|
||||
OS << "{\n";
|
||||
OS << " return float(1.0 / sqrt(max(val.x, 1.E-10))).xxxx;\n";
|
||||
OS << "}\n\n";
|
||||
|
||||
OS << "vec4 log2_legacy(vec4 val)\n";
|
||||
OS << "{\n";
|
||||
OS << " return log2(max(val.x, 1.E-10)).xxxx;\n";
|
||||
OS << "}\n\n";
|
||||
|
||||
OS << "vec4 lit_legacy(vec4 val)";
|
||||
OS << "{\n";
|
||||
OS << " vec4 clamped_val = val;\n";
|
||||
OS << " clamped_val.x = max(val.x, 0);\n";
|
||||
OS << " clamped_val.y = max(val.y, 0);\n";
|
||||
OS << " vec4 result;\n";
|
||||
OS << " result.x = 1.0;\n";
|
||||
OS << " result.w = 1.;\n";
|
||||
OS << " result.y = clamped_val.x;\n";
|
||||
OS << " result.z = clamped_val.x > 0.0 ? exp(clamped_val.w * log(max(clamped_val.y, 1.E-10))) : 0.0;\n";
|
||||
OS << " return result;\n";
|
||||
OS << "}\n\n";
|
||||
}
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
std::string getFloatTypeNameImpl(size_t elementCount);
|
||||
std::string getFunctionImpl(FUNCTION f);
|
||||
std::string compareFunctionImpl(COMPARE f, const std::string &Op0, const std::string &Op1);
|
||||
void insert_glsl_legacy_function(std::ostream& OS);
|
||||
@@ -61,22 +61,39 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS)
|
||||
{
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||
{
|
||||
if (PT.type != "sampler2D")
|
||||
if (PT.type != "sampler1D" &&
|
||||
PT.type != "sampler2D" &&
|
||||
PT.type != "sampler3D" &&
|
||||
PT.type != "samplerCube")
|
||||
continue;
|
||||
for (const ParamItem& PI : PT.items)
|
||||
OS << "uniform " << PT.type << " " << PI.name << ";" << std::endl;
|
||||
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
std::string samplerType = PT.type;
|
||||
int index = atoi(&PI.name.data()[3]);
|
||||
|
||||
if (m_prog.unnormalized_coords & (1 << index))
|
||||
samplerType = "sampler2DRect";
|
||||
|
||||
OS << "uniform " << samplerType << " " << PI.name << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
OS << "layout(std140, binding = 2) uniform FragmentConstantsBuffer" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_UNIFORM])
|
||||
{
|
||||
if (PT.type == "sampler2D")
|
||||
if (PT.type == "sampler1D" ||
|
||||
PT.type == "sampler2D" ||
|
||||
PT.type == "sampler3D" ||
|
||||
PT.type == "samplerCube")
|
||||
continue;
|
||||
|
||||
for (const ParamItem& PI : PT.items)
|
||||
OS << " " << PT.type << " " << PI.name << ";" << std::endl;
|
||||
OS << " " << PT.type << " " << PI.name << ";" << std::endl;
|
||||
}
|
||||
|
||||
// A dummy value otherwise it's invalid to create an empty uniform buffer
|
||||
OS << " vec4 void_value;" << std::endl;
|
||||
OS << "};" << std::endl;
|
||||
@@ -84,22 +101,7 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS)
|
||||
|
||||
void GLFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
|
||||
{
|
||||
// "lib" function
|
||||
// 0.00001 is used as "some non zero very little number"
|
||||
OS << "vec4 divsq_legacy(vec4 num, vec4 denum)\n";
|
||||
OS << "{\n";
|
||||
OS << " return num / sqrt(max(denum.xxxx, 0.00001));\n";
|
||||
OS << "}\n";
|
||||
|
||||
OS << "vec4 rcp_legacy(vec4 denum)\n";
|
||||
OS << "{\n";
|
||||
OS << " return 1. / denum;\n";
|
||||
OS << "}\n";
|
||||
|
||||
OS << "vec4 rsq_legacy(vec4 denum)\n";
|
||||
OS << "{\n";
|
||||
OS << " return 1. / sqrt(max(denum, 0.00001));\n";
|
||||
OS << "}\n";
|
||||
insert_glsl_legacy_function(OS);
|
||||
|
||||
OS << "void main ()" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
@@ -136,9 +138,9 @@ void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS)
|
||||
{
|
||||
{
|
||||
/** Note: Naruto Shippuden : Ultimate Ninja Storm 2 sets CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS in a shader
|
||||
* but it writes depth in r1.z and not h2.z.
|
||||
* Maybe there's a different flag for depth ?
|
||||
*/
|
||||
* but it writes depth in r1.z and not h2.z.
|
||||
* Maybe there's a different flag for depth ?
|
||||
*/
|
||||
//OS << ((m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) ? "\tgl_FragDepth = r1.z;\n" : "\tgl_FragDepth = h0.z;\n") << std::endl;
|
||||
OS << " gl_FragDepth = r1.z;\n";
|
||||
}
|
||||
|
||||
+199
-171
@@ -11,25 +11,44 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
u32 get_max_depth_value(Surface_depth_format format)
|
||||
u32 get_max_depth_value(rsx::surface_depth_format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Surface_depth_format::z16: return 0xFFFF;
|
||||
case Surface_depth_format::z24s8: return 0xFFFFFF;
|
||||
case rsx::surface_depth_format::z16: return 0xFFFF;
|
||||
case rsx::surface_depth_format::z24s8: return 0xFFFFFF;
|
||||
}
|
||||
throw EXCEPTION("Unknow depth format");
|
||||
}
|
||||
|
||||
u8 get_pixel_size(Surface_depth_format format)
|
||||
u8 get_pixel_size(rsx::surface_depth_format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case Surface_depth_format::z16: return 2;
|
||||
case Surface_depth_format::z24s8: return 4;
|
||||
case rsx::surface_depth_format::z16: return 2;
|
||||
case rsx::surface_depth_format::z24s8: return 4;
|
||||
}
|
||||
throw EXCEPTION("Unknow depth format");
|
||||
}
|
||||
|
||||
u32 to_gl_internal_type(rsx::vertex_base_type type, u8 size)
|
||||
{
|
||||
/**
|
||||
* The buffer texture spec only allows fetches aligned to 8, 16, 32, etc...
|
||||
* This rules out most 3-component formats, except for the 32-wide RGB32F, RGB32I, RGB32UI
|
||||
*/
|
||||
const u32 vec1_types[] = { GL_R16, GL_R32F, GL_R16F, GL_R8, GL_R32I, GL_R16F, GL_R8 };
|
||||
const u32 vec2_types[] = { GL_RG16, GL_RG32F, GL_RG16F, GL_RG8, GL_RG32I, GL_RG16F, GL_RG8 };
|
||||
const u32 vec3_types[] = { GL_RGBA16, GL_RGB32F, GL_RGBA16F, GL_RGBA8, GL_RGB32I, GL_RGBA16F, GL_RGBA8 }; //VEC3 COMPONENTS NOT SUPPORTED!
|
||||
const u32 vec4_types[] = { GL_RGBA16, GL_RGBA32F, GL_RGBA16F, GL_RGBA8, GL_RGBA32I, GL_RGBA16F, GL_RGBA8 };
|
||||
|
||||
const u32* vec_selectors[] = { 0, vec1_types, vec2_types, vec3_types, vec4_types };
|
||||
|
||||
if (type > rsx::vertex_base_type::ub256)
|
||||
throw EXCEPTION("OpenGL error: unknown vertex base type 0x%X.", (u32)type);
|
||||
|
||||
return vec_selectors[size][(int)type];
|
||||
}
|
||||
}
|
||||
|
||||
GLGSRender::GLGSRender() : GSRender(frame_type::OpenGL)
|
||||
@@ -120,7 +139,7 @@ void GLGSRender::begin()
|
||||
|
||||
__glcheck glBlendFuncSeparate(sfactor_rgb, dfactor_rgb, sfactor_a, dfactor_a);
|
||||
|
||||
if (m_surface.color_format == Surface_color_format::w16z16y16x16) //TODO: check another color formats
|
||||
if (m_surface.color_format == rsx::surface_color_format::w16z16y16x16) //TODO: check another color formats
|
||||
{
|
||||
u32 blend_color = rsx::method_registers[NV4097_SET_BLEND_COLOR];
|
||||
u32 blend_color2 = rsx::method_registers[NV4097_SET_BLEND_COLOR2];
|
||||
@@ -318,33 +337,33 @@ void apply_attrib_array(gl::glsl::program& program, int location, const std::vec
|
||||
|
||||
namespace
|
||||
{
|
||||
gl::buffer_pointer::type gl_types(Vertex_base_type type)
|
||||
gl::buffer_pointer::type gl_types(rsx::vertex_base_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Vertex_base_type::s1: return gl::buffer_pointer::type::s16;
|
||||
case Vertex_base_type::f: return gl::buffer_pointer::type::f32;
|
||||
case Vertex_base_type::sf: return gl::buffer_pointer::type::f16;
|
||||
case Vertex_base_type::ub: return gl::buffer_pointer::type::u8;
|
||||
case Vertex_base_type::s32k: return gl::buffer_pointer::type::s32;
|
||||
case Vertex_base_type::cmp: return gl::buffer_pointer::type::s16; // Needs conversion
|
||||
case Vertex_base_type::ub256: gl::buffer_pointer::type::u8;
|
||||
case rsx::vertex_base_type::s1: return gl::buffer_pointer::type::s16;
|
||||
case rsx::vertex_base_type::f: return gl::buffer_pointer::type::f32;
|
||||
case rsx::vertex_base_type::sf: return gl::buffer_pointer::type::f16;
|
||||
case rsx::vertex_base_type::ub: return gl::buffer_pointer::type::u8;
|
||||
case rsx::vertex_base_type::s32k: return gl::buffer_pointer::type::s32;
|
||||
case rsx::vertex_base_type::cmp: return gl::buffer_pointer::type::s16; // Needs conversion
|
||||
case rsx::vertex_base_type::ub256: gl::buffer_pointer::type::u8;
|
||||
}
|
||||
throw EXCEPTION("unknow vertex type");
|
||||
}
|
||||
|
||||
bool gl_normalized(Vertex_base_type type)
|
||||
bool gl_normalized(rsx::vertex_base_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Vertex_base_type::s1:
|
||||
case Vertex_base_type::ub:
|
||||
case Vertex_base_type::cmp:
|
||||
case rsx::vertex_base_type::s1:
|
||||
case rsx::vertex_base_type::ub:
|
||||
case rsx::vertex_base_type::cmp:
|
||||
return true;
|
||||
case Vertex_base_type::f:
|
||||
case Vertex_base_type::sf:
|
||||
case Vertex_base_type::ub256:
|
||||
case Vertex_base_type::s32k:
|
||||
case rsx::vertex_base_type::f:
|
||||
case rsx::vertex_base_type::sf:
|
||||
case rsx::vertex_base_type::ub256:
|
||||
case rsx::vertex_base_type::s32k:
|
||||
return false;
|
||||
}
|
||||
throw EXCEPTION("unknow vertex type");
|
||||
@@ -375,6 +394,12 @@ void GLGSRender::end()
|
||||
int location;
|
||||
if (m_program->uniforms.has_location("tex" + std::to_string(i), &location))
|
||||
{
|
||||
u32 target = GL_TEXTURE_2D;
|
||||
if (textures[i].format() & CELL_GCM_TEXTURE_UN)
|
||||
target = GL_TEXTURE_RECTANGLE;
|
||||
|
||||
m_gl_textures[i].set_target(target);
|
||||
|
||||
__glcheck m_gl_textures[i].init(i, textures[i]);
|
||||
glProgramUniform1i(m_program->id(), location, i);
|
||||
}
|
||||
@@ -397,14 +422,14 @@ void GLGSRender::end()
|
||||
};
|
||||
|
||||
u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK];
|
||||
m_vao.bind();
|
||||
|
||||
std::vector<u8> vertex_index_array;
|
||||
vertex_draw_count = 0;
|
||||
u32 min_index, max_index;
|
||||
if (draw_command == Draw_command::draw_command_indexed)
|
||||
|
||||
if (draw_command == rsx::draw_command::indexed)
|
||||
{
|
||||
Index_array_type type = to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
rsx::index_array_type type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
u32 type_size = gsl::narrow<u32>(get_index_type_size(type));
|
||||
for (const auto& first_count : first_count_commands)
|
||||
{
|
||||
@@ -415,17 +440,18 @@ void GLGSRender::end()
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Index_array_type::unsigned_32b:
|
||||
case rsx::index_array_type::u32:
|
||||
std::tie(min_index, max_index) = write_index_array_data_to_buffer_untouched(gsl::span<u32>((u32*)vertex_index_array.data(), vertex_draw_count), first_count_commands);
|
||||
break;
|
||||
case Index_array_type::unsigned_16b:
|
||||
case rsx::index_array_type::u16:
|
||||
std::tie(min_index, max_index) = write_index_array_data_to_buffer_untouched(gsl::span<u16>((u16*)vertex_index_array.data(), vertex_draw_count), first_count_commands);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (draw_command == Draw_command::draw_command_inlined_array)
|
||||
if (draw_command == rsx::draw_command::inlined_array)
|
||||
{
|
||||
vertex_arrays_data.resize(inline_vertex_array.size() * sizeof(u32));
|
||||
write_inline_array_to_buffer(vertex_arrays_data.data());
|
||||
u32 offset = 0;
|
||||
for (int index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
@@ -436,17 +462,30 @@ void GLGSRender::end()
|
||||
continue;
|
||||
|
||||
int location;
|
||||
if (!m_program->attribs.has_location(reg_table[index], &location))
|
||||
if (!m_program->uniforms.has_location(reg_table[index] + "_buffer", &location))
|
||||
continue;
|
||||
|
||||
__glcheck m_program->attribs[location] =
|
||||
(m_vao + offset)
|
||||
.config(gl_types(vertex_info.type), vertex_info.size, gl_normalized(vertex_info.type));
|
||||
const u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size);
|
||||
const u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size);
|
||||
const u32 data_size = element_size * vertex_draw_count;
|
||||
|
||||
auto &buffer = m_gl_attrib_buffers[index].buffer;
|
||||
auto &texture = m_gl_attrib_buffers[index].texture;
|
||||
|
||||
buffer->data(data_size, nullptr);
|
||||
buffer->sub_data(0, data_size, vertex_arrays_data.data()+offset);
|
||||
|
||||
//Attach buffer to texture
|
||||
texture->copy_from(*buffer, gl_type);
|
||||
|
||||
//Link texture to uniform
|
||||
m_program->uniforms.texture(location, index +rsx::limits::vertex_count, *texture);
|
||||
|
||||
offset += rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size);
|
||||
}
|
||||
}
|
||||
|
||||
if (draw_command == Draw_command::draw_command_array)
|
||||
if (draw_command == rsx::draw_command::array)
|
||||
{
|
||||
for (const auto &first_count : first_count_commands)
|
||||
{
|
||||
@@ -454,7 +493,7 @@ void GLGSRender::end()
|
||||
}
|
||||
}
|
||||
|
||||
if (draw_command == Draw_command::draw_command_array || draw_command == Draw_command::draw_command_indexed)
|
||||
if (draw_command == rsx::draw_command::array || draw_command == rsx::draw_command::indexed)
|
||||
{
|
||||
for (int index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
{
|
||||
@@ -463,7 +502,7 @@ void GLGSRender::end()
|
||||
continue;
|
||||
|
||||
int location;
|
||||
if (!m_program->attribs.has_location(reg_table[index], &location))
|
||||
if (!m_program->uniforms.has_location(reg_table[index]+"_buffer", &location))
|
||||
continue;
|
||||
|
||||
if (vertex_arrays_info[index].size > 0)
|
||||
@@ -475,7 +514,7 @@ void GLGSRender::end()
|
||||
// Fill vertex_array
|
||||
u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size);
|
||||
vertex_array.resize(vertex_draw_count * element_size);
|
||||
if (draw_command == Draw_command::draw_command_array)
|
||||
if (draw_command == rsx::draw_command::array)
|
||||
{
|
||||
size_t offset = 0;
|
||||
for (const auto &first_count : first_count_commands)
|
||||
@@ -484,7 +523,7 @@ void GLGSRender::end()
|
||||
offset += first_count.second * element_size;
|
||||
}
|
||||
}
|
||||
if (draw_command == Draw_command::draw_command_indexed)
|
||||
if (draw_command == rsx::draw_command::indexed)
|
||||
{
|
||||
vertex_array.resize((max_index + 1) * element_size);
|
||||
write_vertex_array_data_to_buffer(vertex_array.data(), 0, max_index + 1, index, vertex_info);
|
||||
@@ -495,29 +534,48 @@ void GLGSRender::end()
|
||||
vertex_arrays_offsets[index] = gsl::narrow<u32>(position);
|
||||
vertex_arrays_data.resize(position + size);
|
||||
|
||||
memcpy(vertex_arrays_data.data() + position, vertex_array.data(), size);
|
||||
const u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size);
|
||||
const u32 data_size = element_size * vertex_draw_count;
|
||||
|
||||
__glcheck m_program->attribs[location] =
|
||||
(m_vao + vertex_arrays_offsets[index])
|
||||
.config(gl_types(vertex_info.type), vertex_info.size, gl_normalized(vertex_info.type));
|
||||
auto &buffer = m_gl_attrib_buffers[index].buffer;
|
||||
auto &texture = m_gl_attrib_buffers[index].texture;
|
||||
|
||||
buffer->data(data_size, nullptr);
|
||||
buffer->sub_data(0, data_size, vertex_array.data());
|
||||
|
||||
//Attach buffer to texture
|
||||
texture->copy_from(*buffer, gl_type);
|
||||
|
||||
//Link texture to uniform
|
||||
m_program->uniforms.texture(location, index + rsx::limits::vertex_count, *texture);
|
||||
}
|
||||
else if (register_vertex_info[index].size > 0)
|
||||
{
|
||||
//Untested!
|
||||
auto &vertex_data = register_vertex_data[index];
|
||||
auto &vertex_info = register_vertex_info[index];
|
||||
|
||||
switch (vertex_info.type)
|
||||
{
|
||||
case Vertex_base_type::f:
|
||||
switch (register_vertex_info[index].size)
|
||||
{
|
||||
case 1: apply_attrib_array<f32, 1>(*m_program, location, vertex_data); break;
|
||||
case 2: apply_attrib_array<f32, 2>(*m_program, location, vertex_data); break;
|
||||
case 3: apply_attrib_array<f32, 3>(*m_program, location, vertex_data); break;
|
||||
case 4: apply_attrib_array<f32, 4>(*m_program, location, vertex_data); break;
|
||||
}
|
||||
break;
|
||||
case rsx::vertex_base_type::f:
|
||||
{
|
||||
const u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size);
|
||||
const u32 gl_type = to_gl_internal_type(vertex_info.type, vertex_info.size);
|
||||
const size_t data_size = vertex_data.size();
|
||||
|
||||
auto &buffer = m_gl_attrib_buffers[index].buffer;
|
||||
auto &texture = m_gl_attrib_buffers[index].texture;
|
||||
|
||||
buffer->data(data_size, nullptr);
|
||||
buffer->sub_data(0, data_size, vertex_data.data());
|
||||
|
||||
//Attach buffer to texture
|
||||
texture->copy_from(*buffer, gl_type);
|
||||
|
||||
//Link texture to uniform
|
||||
m_program->uniforms.texture(location, index + rsx::limits::vertex_count, *texture);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_ERROR(RSX, "bad non array vertex data format (type = %d, size = %d)", vertex_info.type, vertex_info.size);
|
||||
break;
|
||||
@@ -525,17 +583,28 @@ void GLGSRender::end()
|
||||
}
|
||||
}
|
||||
}
|
||||
m_vbo.data(vertex_arrays_data.size(), vertex_arrays_data.data());
|
||||
|
||||
if (draw_command == Draw_command::draw_command_indexed)
|
||||
// glDraw* will fail without at least attrib0 defined if we are on compatibility profile
|
||||
// Someone should really test AMD behaviour here, Nvidia is too permissive. There is no buffer currently bound, but on NV it works ok
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
|
||||
|
||||
/**
|
||||
* Validate fails if called right after linking a program because the VS and FS both use textures bound using different
|
||||
* samplers. So far only sampler2D has been largely used, hiding the problem. This call shall also degrade performance further
|
||||
* if used every draw call. Fixes shader validation issues on AMD.
|
||||
*/
|
||||
m_program->validate();
|
||||
|
||||
if (draw_command == rsx::draw_command::indexed)
|
||||
{
|
||||
m_ebo.data(vertex_index_array.size(), vertex_index_array.data());
|
||||
|
||||
Index_array_type indexed_type = to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
rsx::index_array_type indexed_type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
|
||||
|
||||
if (indexed_type == Index_array_type::unsigned_32b)
|
||||
if (indexed_type == rsx::index_array_type::u32)
|
||||
__glcheck glDrawElements(gl::draw_mode(draw_mode), vertex_draw_count, GL_UNSIGNED_INT, nullptr);
|
||||
if (indexed_type == Index_array_type::unsigned_16b)
|
||||
if (indexed_type == rsx::index_array_type::u16)
|
||||
__glcheck glDrawElements(gl::draw_mode(draw_mode), vertex_draw_count, GL_UNSIGNED_SHORT, nullptr);
|
||||
}
|
||||
else
|
||||
@@ -567,10 +636,10 @@ void GLGSRender::set_viewport()
|
||||
|
||||
u32 shader_window = rsx::method_registers[NV4097_SET_SHADER_WINDOW];
|
||||
|
||||
u8 shader_window_origin = (shader_window >> 12) & 0xf;
|
||||
rsx::window_origin shader_window_origin = rsx::to_window_origin((shader_window >> 12) & 0xf);
|
||||
|
||||
//TODO
|
||||
if (true || shader_window_origin == CELL_GCM_WINDOW_ORIGIN_BOTTOM)
|
||||
if (true || shader_window_origin == rsx::window_origin::bottom)
|
||||
{
|
||||
__glcheck glViewport(viewport_x, viewport_y, viewport_w, viewport_h);
|
||||
__glcheck glScissor(scissor_x, scissor_y, scissor_w, scissor_h);
|
||||
@@ -609,14 +678,25 @@ void GLGSRender::on_init_thread()
|
||||
|
||||
m_vao.array_buffer = m_vbo;
|
||||
m_vao.element_array_buffer = m_ebo;
|
||||
|
||||
for (texture_buffer_pair &attrib_buffer : m_gl_attrib_buffers)
|
||||
{
|
||||
gl::texture *&tex = attrib_buffer.texture;
|
||||
tex = new gl::texture(gl::texture::target::textureBuffer);
|
||||
tex->create();
|
||||
tex->set_target(gl::texture::target::textureBuffer);
|
||||
|
||||
gl::buffer *&buf = attrib_buffer.buffer;
|
||||
buf = new gl::buffer();
|
||||
buf->create();
|
||||
}
|
||||
}
|
||||
|
||||
void GLGSRender::on_exit()
|
||||
{
|
||||
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
|
||||
//if (m_program)
|
||||
// m_program.remove();
|
||||
m_prog_buffer.clear();
|
||||
|
||||
if (draw_fbo)
|
||||
draw_fbo.remove();
|
||||
@@ -650,6 +730,19 @@ void GLGSRender::on_exit()
|
||||
|
||||
if (m_fragment_constants_buffer)
|
||||
m_fragment_constants_buffer.remove();
|
||||
|
||||
for (texture_buffer_pair &attrib_buffer : m_gl_attrib_buffers)
|
||||
{
|
||||
gl::texture *&tex = attrib_buffer.texture;
|
||||
tex->remove();
|
||||
delete tex;
|
||||
tex = nullptr;
|
||||
|
||||
gl::buffer *&buf = attrib_buffer.buffer;
|
||||
buf->remove();
|
||||
delete buf;
|
||||
buf = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void nv4097_clear_surface(u32 arg, GLGSRender* renderer)
|
||||
@@ -677,7 +770,7 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer)
|
||||
|
||||
if (arg & 0x1)
|
||||
{
|
||||
Surface_depth_format surface_depth_format = to_surface_depth_format((rsx::method_registers[NV4097_SET_SURFACE_FORMAT] >> 5) & 0x7);
|
||||
rsx::surface_depth_format surface_depth_format = rsx::to_surface_depth_format((rsx::method_registers[NV4097_SET_SURFACE_FORMAT] >> 5) & 0x7);
|
||||
u32 max_depth_value = get_max_depth_value(surface_depth_format);
|
||||
|
||||
u32 clear_depth = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8;
|
||||
@@ -738,73 +831,8 @@ bool GLGSRender::do_method(u32 cmd, u32 arg)
|
||||
bool GLGSRender::load_program()
|
||||
{
|
||||
#if 1
|
||||
RSXVertexProgram vertex_program;
|
||||
u32 transform_program_start = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START];
|
||||
vertex_program.data.reserve((512 - transform_program_start) * 4);
|
||||
|
||||
for (int i = transform_program_start; i < 512; ++i)
|
||||
{
|
||||
vertex_program.data.resize((i - transform_program_start) * 4 + 4);
|
||||
memcpy(vertex_program.data.data() + (i - transform_program_start) * 4, transform_program + i * 4, 4 * sizeof(u32));
|
||||
|
||||
D3 d3;
|
||||
d3.HEX = transform_program[i * 4 + 3];
|
||||
|
||||
if (d3.end)
|
||||
break;
|
||||
}
|
||||
vertex_program.output_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK];
|
||||
|
||||
u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK];
|
||||
u32 modulo_mask = rsx::method_registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION];
|
||||
vertex_program.rsx_vertex_inputs.clear();
|
||||
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
{
|
||||
bool enabled = !!(input_mask & (1 << index));
|
||||
if (!enabled)
|
||||
continue;
|
||||
|
||||
if (vertex_arrays_info[index].size > 0)
|
||||
{
|
||||
vertex_program.rsx_vertex_inputs.push_back(
|
||||
{
|
||||
index,
|
||||
vertex_arrays_info[index].size,
|
||||
vertex_arrays_info[index].frequency,
|
||||
!!((modulo_mask >> index) & 0x1),
|
||||
true
|
||||
}
|
||||
);
|
||||
}
|
||||
else if (register_vertex_info[index].size > 0)
|
||||
{
|
||||
vertex_program.rsx_vertex_inputs.push_back(
|
||||
{
|
||||
index,
|
||||
register_vertex_info[index].size,
|
||||
register_vertex_info[index].frequency,
|
||||
!!((modulo_mask >> index) & 0x1),
|
||||
false
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
RSXFragmentProgram fragment_program;
|
||||
u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
|
||||
fragment_program.offset = shader_program & ~0x3;
|
||||
fragment_program.addr = rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1);
|
||||
fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL];
|
||||
|
||||
for (u32 i = 0; i < rsx::limits::textures_count; ++i)
|
||||
{
|
||||
if (!textures[i].enabled())
|
||||
fragment_program.texture_dimensions.push_back(texture_dimension::texture_dimension_2d);
|
||||
else if (textures[i].cubemap())
|
||||
fragment_program.texture_dimensions.push_back(texture_dimension::texture_dimension_cubemap);
|
||||
else
|
||||
fragment_program.texture_dimensions.push_back(texture_dimension::texture_dimension_2d);
|
||||
}
|
||||
RSXVertexProgram vertex_program = get_current_vertex_program();
|
||||
RSXFragmentProgram fragment_program = get_current_fragment_program();
|
||||
|
||||
__glcheck m_program = &m_prog_buffer.getGraphicPipelineState(vertex_program, fragment_program, nullptr);
|
||||
__glcheck m_program->use();
|
||||
@@ -891,52 +919,52 @@ struct color_format
|
||||
color_swizzle swizzle;
|
||||
};
|
||||
|
||||
color_format surface_color_format_to_gl(Surface_color_format color_format)
|
||||
color_format surface_color_format_to_gl(rsx::surface_color_format color_format)
|
||||
{
|
||||
//color format
|
||||
switch (color_format)
|
||||
{
|
||||
case Surface_color_format::r5g6b5:
|
||||
case rsx::surface_color_format::r5g6b5:
|
||||
return{ gl::texture::type::ushort_5_6_5, gl::texture::format::bgr, false, 3, 2 };
|
||||
|
||||
case Surface_color_format::a8r8g8b8:
|
||||
case rsx::surface_color_format::a8r8g8b8:
|
||||
return{ gl::texture::type::uint_8_8_8_8, gl::texture::format::bgra, false, 4, 1 };
|
||||
|
||||
case Surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
case rsx::surface_color_format::x8r8g8b8_o8r8g8b8:
|
||||
return{ gl::texture::type::uint_8_8_8_8, gl::texture::format::bgra, false, 4, 1,
|
||||
{ gl::texture::channel::one, gl::texture::channel::r, gl::texture::channel::g, gl::texture::channel::b } };
|
||||
|
||||
case Surface_color_format::w16z16y16x16:
|
||||
case rsx::surface_color_format::w16z16y16x16:
|
||||
return{ gl::texture::type::f16, gl::texture::format::rgba, true, 4, 2 };
|
||||
|
||||
case Surface_color_format::w32z32y32x32:
|
||||
case rsx::surface_color_format::w32z32y32x32:
|
||||
return{ gl::texture::type::f32, gl::texture::format::rgba, true, 4, 4 };
|
||||
|
||||
case Surface_color_format::b8:
|
||||
case Surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case Surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
case Surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case Surface_color_format::g8b8:
|
||||
case Surface_color_format::x32:
|
||||
case Surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case Surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case Surface_color_format::a8b8g8r8:
|
||||
case rsx::surface_color_format::b8:
|
||||
case rsx::surface_color_format::x1r5g5b5_o1r5g5b5:
|
||||
case rsx::surface_color_format::x1r5g5b5_z1r5g5b5:
|
||||
case rsx::surface_color_format::x8r8g8b8_z8r8g8b8:
|
||||
case rsx::surface_color_format::g8b8:
|
||||
case rsx::surface_color_format::x32:
|
||||
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
|
||||
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
|
||||
case rsx::surface_color_format::a8b8g8r8:
|
||||
default:
|
||||
LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", color_format);
|
||||
return{ gl::texture::type::uint_8_8_8_8, gl::texture::format::bgra, false, 4, 1 };
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<gl::texture::type, gl::texture::format> surface_depth_format_to_gl(Surface_depth_format depth_format)
|
||||
std::pair<gl::texture::type, gl::texture::format> surface_depth_format_to_gl(rsx::surface_depth_format depth_format)
|
||||
{
|
||||
switch (depth_format)
|
||||
{
|
||||
case Surface_depth_format::z16:
|
||||
case rsx::surface_depth_format::z16:
|
||||
return std::make_pair(gl::texture::type::ushort, gl::texture::format::depth);
|
||||
|
||||
default:
|
||||
LOG_ERROR(RSX, "Surface depth buffer: Unsupported surface depth format (0x%x)", depth_format);
|
||||
case Surface_depth_format::z24s8:
|
||||
case rsx::surface_depth_format::z24s8:
|
||||
return std::make_pair(gl::texture::type::uint_24_8, gl::texture::format::depth_stencil);
|
||||
//return std::make_pair(gl::texture::type::f32, gl::texture::format::depth);
|
||||
}
|
||||
@@ -985,7 +1013,7 @@ void GLGSRender::init_buffers(bool skip_reading)
|
||||
|
||||
switch (m_surface.depth_format)
|
||||
{
|
||||
case Surface_depth_format::z16:
|
||||
case rsx::surface_depth_format::z16:
|
||||
{
|
||||
__glcheck m_draw_tex_depth_stencil.config()
|
||||
.size({ (int)m_surface.width, (int)m_surface.height })
|
||||
@@ -997,7 +1025,7 @@ void GLGSRender::init_buffers(bool skip_reading)
|
||||
break;
|
||||
}
|
||||
|
||||
case Surface_depth_format::z24s8:
|
||||
case rsx::surface_depth_format::z24s8:
|
||||
{
|
||||
__glcheck m_draw_tex_depth_stencil.config()
|
||||
.size({ (int)m_surface.width, (int)m_surface.height })
|
||||
@@ -1028,27 +1056,27 @@ void GLGSRender::init_buffers(bool skip_reading)
|
||||
|
||||
set_viewport();
|
||||
|
||||
switch (to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
|
||||
switch (rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
|
||||
{
|
||||
case Surface_target::none: break;
|
||||
case rsx::surface_target::none: break;
|
||||
|
||||
case Surface_target::surface_a:
|
||||
case rsx::surface_target::surface_a:
|
||||
__glcheck draw_fbo.draw_buffer(draw_fbo.color[0]);
|
||||
break;
|
||||
|
||||
case Surface_target::surface_b:
|
||||
case rsx::surface_target::surface_b:
|
||||
__glcheck draw_fbo.draw_buffer(draw_fbo.color[1] );
|
||||
break;
|
||||
|
||||
case Surface_target::surfaces_a_b:
|
||||
case rsx::surface_target::surfaces_a_b:
|
||||
__glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1] });
|
||||
break;
|
||||
|
||||
case Surface_target::surfaces_a_b_c:
|
||||
case rsx::surface_target::surfaces_a_b_c:
|
||||
__glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1], draw_fbo.color[2] });
|
||||
break;
|
||||
|
||||
case Surface_target::surfaces_a_b_c_d:
|
||||
case rsx::surface_target::surfaces_a_b_c_d:
|
||||
__glcheck draw_fbo.draw_buffers({ draw_fbo.color[0], draw_fbo.color[1], draw_fbo.color[2], draw_fbo.color[3] });
|
||||
break;
|
||||
|
||||
@@ -1126,28 +1154,28 @@ void GLGSRender::read_buffers()
|
||||
}
|
||||
};
|
||||
|
||||
switch (to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
|
||||
switch (rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
|
||||
{
|
||||
case Surface_target::none:
|
||||
case rsx::surface_target::none:
|
||||
break;
|
||||
|
||||
case Surface_target::surface_a:
|
||||
case rsx::surface_target::surface_a:
|
||||
read_color_buffers(0, 1);
|
||||
break;
|
||||
|
||||
case Surface_target::surface_b:
|
||||
case rsx::surface_target::surface_b:
|
||||
read_color_buffers(1, 1);
|
||||
break;
|
||||
|
||||
case Surface_target::surfaces_a_b:
|
||||
case rsx::surface_target::surfaces_a_b:
|
||||
read_color_buffers(0, 2);
|
||||
break;
|
||||
|
||||
case Surface_target::surfaces_a_b_c:
|
||||
case rsx::surface_target::surfaces_a_b_c:
|
||||
read_color_buffers(0, 3);
|
||||
break;
|
||||
|
||||
case Surface_target::surfaces_a_b_c_d:
|
||||
case rsx::surface_target::surfaces_a_b_c_d:
|
||||
read_color_buffers(0, 4);
|
||||
break;
|
||||
}
|
||||
@@ -1171,7 +1199,7 @@ void GLGSRender::read_buffers()
|
||||
{
|
||||
u32 depth_address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]);
|
||||
|
||||
if (m_surface.depth_format == Surface_depth_format::z16)
|
||||
if (m_surface.depth_format == rsx::surface_depth_format::z16)
|
||||
{
|
||||
u16 *dst = (u16*)pixels;
|
||||
const be_t<u16>* src = vm::ps3::_ptr<u16>(depth_address);
|
||||
@@ -1257,28 +1285,28 @@ void GLGSRender::write_buffers()
|
||||
}
|
||||
};
|
||||
|
||||
switch (to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
|
||||
switch (rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))
|
||||
{
|
||||
case Surface_target::none:
|
||||
case rsx::surface_target::none:
|
||||
break;
|
||||
|
||||
case Surface_target::surface_a:
|
||||
case rsx::surface_target::surface_a:
|
||||
write_color_buffers(0, 1);
|
||||
break;
|
||||
|
||||
case Surface_target::surface_b:
|
||||
case rsx::surface_target::surface_b:
|
||||
write_color_buffers(1, 1);
|
||||
break;
|
||||
|
||||
case Surface_target::surfaces_a_b:
|
||||
case rsx::surface_target::surfaces_a_b:
|
||||
write_color_buffers(0, 2);
|
||||
break;
|
||||
|
||||
case Surface_target::surfaces_a_b_c:
|
||||
case rsx::surface_target::surfaces_a_b_c:
|
||||
write_color_buffers(0, 3);
|
||||
break;
|
||||
|
||||
case Surface_target::surfaces_a_b_c_d:
|
||||
case rsx::surface_target::surfaces_a_b_c_d:
|
||||
write_color_buffers(0, 4);
|
||||
break;
|
||||
}
|
||||
@@ -1305,7 +1333,7 @@ void GLGSRender::write_buffers()
|
||||
{
|
||||
u32 depth_address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]);
|
||||
|
||||
if (m_surface.depth_format == Surface_depth_format::z16)
|
||||
if (m_surface.depth_format == rsx::surface_depth_format::z16)
|
||||
{
|
||||
const u16 *src = (const u16*)pixels;
|
||||
be_t<u16>* dst = vm::ps3::_ptr<u16>(depth_address);
|
||||
|
||||
@@ -22,6 +22,13 @@ private:
|
||||
|
||||
rsx::surface_info m_surface;
|
||||
|
||||
struct texture_buffer_pair
|
||||
{
|
||||
gl::texture *texture;
|
||||
gl::buffer *buffer;
|
||||
}
|
||||
m_gl_attrib_buffers[rsx::limits::vertex_count];
|
||||
|
||||
public:
|
||||
gl::fbo draw_fbo;
|
||||
|
||||
|
||||
@@ -166,6 +166,10 @@ OPENGL_PROC(PFNGLCHECKFRAMEBUFFERSTATUSPROC, CheckFramebufferStatus);
|
||||
|
||||
OPENGL_PROC(PFNGLBINDBUFFERBASEPROC, BindBufferBase);
|
||||
|
||||
//Texture Buffers
|
||||
OPENGL_PROC(PFNGLTEXBUFFERPROC, TexBuffer);
|
||||
OPENGL_PROC(PFNGLTEXTUREBUFFERRANGEEXTPROC, TextureBufferRangeEXT);
|
||||
|
||||
//KHR_debug
|
||||
OPENGL_PROC(PFNGLDEBUGMESSAGECONTROLARBPROC, DebugMessageControlARB);
|
||||
OPENGL_PROC(PFNGLDEBUGMESSAGEINSERTARBPROC, DebugMessageInsertARB);
|
||||
|
||||
@@ -27,7 +27,7 @@ std::string GLVertexDecompilerThread::compareFunction(COMPARE f, const std::stri
|
||||
|
||||
void GLVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
||||
{
|
||||
OS << "#version 420" << std::endl << std::endl;
|
||||
OS << "#version 430" << std::endl << std::endl;
|
||||
OS << "layout(std140, binding = 0) uniform ScaleOffsetBuffer" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
OS << " mat4 scaleOffsetMat;" << std::endl;
|
||||
@@ -36,10 +36,33 @@ void GLVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
||||
|
||||
void GLVertexDecompilerThread::insertInputs(std::stringstream & OS, const std::vector<ParamType>& inputs)
|
||||
{
|
||||
for (const ParamType PT : inputs)
|
||||
std::vector<std::tuple<size_t, std::string>> input_data;
|
||||
for (const ParamType &PT : inputs)
|
||||
{
|
||||
for (const ParamItem &PI : PT.items)
|
||||
OS << /*"layout(location = " << PI.location << ") "*/ "in " << PT.type << " " << PI.name << ";" << std::endl;
|
||||
{
|
||||
input_data.push_back(std::make_tuple(PI.location, PI.name));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Its is important that the locations are in the order that vertex attributes are expected.
|
||||
* If order is not adhered to, channels may be swapped leading to corruption
|
||||
*/
|
||||
|
||||
std::sort(input_data.begin(), input_data.end());
|
||||
|
||||
int location = 1;
|
||||
for (const std::tuple<size_t, std::string> item : input_data)
|
||||
{
|
||||
for (const ParamType &PT : inputs)
|
||||
{
|
||||
for (const ParamItem &PI : PT.items)
|
||||
{
|
||||
if (PI.name == std::get<1>(item))
|
||||
OS << "layout(location=" << location++ << ")" << " uniform samplerBuffer" << " " << PI.name << "_buffer;" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,9 +124,42 @@ void GLVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::
|
||||
}
|
||||
}
|
||||
|
||||
void add_input(std::stringstream & OS, const ParamItem &PI, const std::vector<rsx_vertex_input> &inputs)
|
||||
{
|
||||
for (const auto &real_input : inputs)
|
||||
{
|
||||
if (real_input.location != PI.location)
|
||||
continue;
|
||||
|
||||
if (!real_input.is_array)
|
||||
{
|
||||
OS << " vec4 " << PI.name << " = texelFetch(" << PI.name << "_buffer, 0);" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (real_input.frequency > 1)
|
||||
{
|
||||
if (real_input.is_modulo)
|
||||
{
|
||||
OS << " vec4 " << PI.name << "= texelFetch(" << PI.name << "_buffer, gl_VertexID %" << real_input.frequency << ");" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
OS << " vec4 " << PI.name << "= texelFetch(" << PI.name << "_buffer, gl_VertexID /" << real_input.frequency << ");" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
OS << " vec4 " << PI.name << "= texelFetch(" << PI.name << "_buffer, gl_VertexID);" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
OS << " vec4 " << PI.name << " = vec4(0., 0., 0., 1.);" << std::endl;
|
||||
}
|
||||
|
||||
void GLVertexDecompilerThread::insertMainStart(std::stringstream & OS)
|
||||
{
|
||||
insert_glsl_legacy_function(OS);
|
||||
|
||||
OS << "void main()" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
|
||||
@@ -118,6 +174,12 @@ void GLVertexDecompilerThread::insertMainStart(std::stringstream & OS)
|
||||
OS << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
for (const ParamType &PT : m_parr.params[PF_PARAM_IN])
|
||||
{
|
||||
for (const ParamItem &PI : PT.items)
|
||||
add_input(OS, PI, rsx_vertex_program.rsx_vertex_inputs);
|
||||
}
|
||||
}
|
||||
|
||||
void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
|
||||
|
||||
@@ -19,10 +19,13 @@ protected:
|
||||
virtual void insertOutputs(std::stringstream &OS, const std::vector<ParamType> &outputs) override;
|
||||
virtual void insertMainStart(std::stringstream &OS) override;
|
||||
virtual void insertMainEnd(std::stringstream &OS) override;
|
||||
|
||||
const RSXVertexProgram &rsx_vertex_program;
|
||||
public:
|
||||
GLVertexDecompilerThread(const RSXVertexProgram &prog, std::string& shader, ParamArray& parr)
|
||||
: VertexProgramDecompiler(prog)
|
||||
, m_shader(shader)
|
||||
, rsx_vertex_program(prog)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -5,20 +5,20 @@ namespace gl
|
||||
{
|
||||
const fbo screen{};
|
||||
|
||||
GLenum draw_mode(Primitive_type in)
|
||||
GLenum draw_mode(rsx::primitive_type in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case Primitive_type::points: return GL_POINTS;
|
||||
case Primitive_type::lines: return GL_LINES;
|
||||
case Primitive_type::line_loop: return GL_LINE_LOOP;
|
||||
case Primitive_type::line_strip: return GL_LINE_STRIP;
|
||||
case Primitive_type::triangles: return GL_TRIANGLES;
|
||||
case Primitive_type::triangle_strip: return GL_TRIANGLE_STRIP;
|
||||
case Primitive_type::triangle_fan: return GL_TRIANGLE_FAN;
|
||||
case Primitive_type::quads: return GL_QUADS;
|
||||
case Primitive_type::quad_strip: return GL_QUAD_STRIP;
|
||||
case Primitive_type::polygon: return GL_POLYGON;
|
||||
case rsx::primitive_type::points: return GL_POINTS;
|
||||
case rsx::primitive_type::lines: return GL_LINES;
|
||||
case rsx::primitive_type::line_loop: return GL_LINE_LOOP;
|
||||
case rsx::primitive_type::line_strip: return GL_LINE_STRIP;
|
||||
case rsx::primitive_type::triangles: return GL_TRIANGLES;
|
||||
case rsx::primitive_type::triangle_strip: return GL_TRIANGLE_STRIP;
|
||||
case rsx::primitive_type::triangle_fan: return GL_TRIANGLE_FAN;
|
||||
case rsx::primitive_type::quads: return GL_QUADS;
|
||||
case rsx::primitive_type::quad_strip: return GL_QUAD_STRIP;
|
||||
case rsx::primitive_type::polygon: return GL_POLYGON;
|
||||
}
|
||||
throw new EXCEPTION("unknow primitive type");
|
||||
}
|
||||
@@ -97,74 +97,74 @@ namespace gl
|
||||
__glcheck glDrawBuffers((GLsizei)ids.size(), ids.data());
|
||||
}
|
||||
|
||||
void fbo::draw_arrays(Primitive_type mode, GLsizei count, GLint first) const
|
||||
void fbo::draw_arrays(rsx::primitive_type mode, GLsizei count, GLint first) const
|
||||
{
|
||||
save_binding_state save(*this);
|
||||
__glcheck glDrawArrays(draw_mode(mode), first, count);
|
||||
}
|
||||
|
||||
void fbo::draw_arrays(const buffer& buffer, Primitive_type mode, GLsizei count, GLint first) const
|
||||
void fbo::draw_arrays(const buffer& buffer, rsx::primitive_type mode, GLsizei count, GLint first) const
|
||||
{
|
||||
buffer.bind(buffer::target::array);
|
||||
draw_arrays(mode, count, first);
|
||||
}
|
||||
|
||||
void fbo::draw_arrays(const vao& buffer, Primitive_type mode, GLsizei count, GLint first) const
|
||||
void fbo::draw_arrays(const vao& buffer, rsx::primitive_type mode, GLsizei count, GLint first) const
|
||||
{
|
||||
buffer.bind();
|
||||
draw_arrays(mode, count, first);
|
||||
}
|
||||
|
||||
void fbo::draw_elements(Primitive_type mode, GLsizei count, indices_type type, const GLvoid *indices) const
|
||||
void fbo::draw_elements(rsx::primitive_type mode, GLsizei count, indices_type type, const GLvoid *indices) const
|
||||
{
|
||||
save_binding_state save(*this);
|
||||
__glcheck glDrawElements(draw_mode(mode), count, (GLenum)type, indices);
|
||||
}
|
||||
|
||||
void fbo::draw_elements(const buffer& buffer, Primitive_type mode, GLsizei count, indices_type type, const GLvoid *indices) const
|
||||
void fbo::draw_elements(const buffer& buffer, rsx::primitive_type mode, GLsizei count, indices_type type, const GLvoid *indices) const
|
||||
{
|
||||
buffer.bind(buffer::target::array);
|
||||
__glcheck glDrawElements(draw_mode(mode), count, (GLenum)type, indices);
|
||||
}
|
||||
|
||||
void fbo::draw_elements(Primitive_type mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset) const
|
||||
void fbo::draw_elements(rsx::primitive_type mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset) const
|
||||
{
|
||||
indices.bind(buffer::target::element_array);
|
||||
__glcheck glDrawElements(draw_mode(mode), count, (GLenum)type, (GLvoid*)indices_buffer_offset);
|
||||
}
|
||||
|
||||
void fbo::draw_elements(const buffer& buffer_, Primitive_type mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset) const
|
||||
void fbo::draw_elements(const buffer& buffer_, rsx::primitive_type mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset) const
|
||||
{
|
||||
buffer_.bind(buffer::target::array);
|
||||
draw_elements(mode, count, type, indices, indices_buffer_offset);
|
||||
}
|
||||
|
||||
void fbo::draw_elements(Primitive_type mode, GLsizei count, const GLubyte *indices) const
|
||||
void fbo::draw_elements(rsx::primitive_type mode, GLsizei count, const GLubyte *indices) const
|
||||
{
|
||||
draw_elements(mode, count, indices_type::ubyte, indices);
|
||||
}
|
||||
|
||||
void fbo::draw_elements(const buffer& buffer, Primitive_type mode, GLsizei count, const GLubyte *indices) const
|
||||
void fbo::draw_elements(const buffer& buffer, rsx::primitive_type mode, GLsizei count, const GLubyte *indices) const
|
||||
{
|
||||
draw_elements(buffer, mode, count, indices_type::ubyte, indices);
|
||||
}
|
||||
|
||||
void fbo::draw_elements(Primitive_type mode, GLsizei count, const GLushort *indices) const
|
||||
void fbo::draw_elements(rsx::primitive_type mode, GLsizei count, const GLushort *indices) const
|
||||
{
|
||||
draw_elements(mode, count, indices_type::ushort, indices);
|
||||
}
|
||||
|
||||
void fbo::draw_elements(const buffer& buffer, Primitive_type mode, GLsizei count, const GLushort *indices) const
|
||||
void fbo::draw_elements(const buffer& buffer, rsx::primitive_type mode, GLsizei count, const GLushort *indices) const
|
||||
{
|
||||
draw_elements(buffer, mode, count, indices_type::ushort, indices);
|
||||
}
|
||||
|
||||
void fbo::draw_elements(Primitive_type mode, GLsizei count, const GLuint *indices) const
|
||||
void fbo::draw_elements(rsx::primitive_type mode, GLsizei count, const GLuint *indices) const
|
||||
{
|
||||
draw_elements(mode, count, indices_type::uint, indices);
|
||||
}
|
||||
|
||||
void fbo::draw_elements(const buffer& buffer, Primitive_type mode, GLsizei count, const GLuint *indices) const
|
||||
void fbo::draw_elements(const buffer& buffer, rsx::primitive_type mode, GLsizei count, const GLuint *indices) const
|
||||
{
|
||||
draw_elements(buffer, mode, count, indices_type::uint, indices);
|
||||
}
|
||||
|
||||
@@ -830,7 +830,8 @@ namespace gl
|
||||
{
|
||||
texture1D = GL_TEXTURE_1D,
|
||||
texture2D = GL_TEXTURE_2D,
|
||||
texture3D = GL_TEXTURE_3D
|
||||
texture3D = GL_TEXTURE_3D,
|
||||
textureBuffer = GL_TEXTURE_BUFFER
|
||||
};
|
||||
|
||||
enum class channel_type
|
||||
@@ -863,9 +864,10 @@ namespace gl
|
||||
GLenum pname;
|
||||
switch (new_binding.get_target())
|
||||
{
|
||||
case target::texture1D: pname = GL_TEXTURE_1D_BINDING_EXT; break;
|
||||
case target::texture2D: pname = GL_TEXTURE_2D_BINDING_EXT; break;
|
||||
case target::texture3D: pname = GL_TEXTURE_3D_BINDING_EXT; break;
|
||||
case target::texture1D: pname = GL_TEXTURE_BINDING_1D; break;
|
||||
case target::texture2D: pname = GL_TEXTURE_BINDING_2D; break;
|
||||
case target::texture3D: pname = GL_TEXTURE_BINDING_3D; break;
|
||||
case target::textureBuffer: pname = GL_TEXTURE_BINDING_BUFFER; break;
|
||||
}
|
||||
|
||||
glGetIntegerv(pname, &m_last_binding);
|
||||
@@ -1131,6 +1133,29 @@ namespace gl
|
||||
__glcheck glTexSubImage2D((GLenum)get_target(), level(), 0, 0, width(), height(), (GLenum)format, (GLenum)type, src);
|
||||
}
|
||||
|
||||
void copy_from(buffer &buf, u32 gl_format_type, u32 offset, u32 length)
|
||||
{
|
||||
if (get_target() != target::textureBuffer)
|
||||
throw EXCEPTION("OpenGL error: texture cannot copy from buffer");
|
||||
|
||||
if (!offset)
|
||||
{
|
||||
copy_from(buf, gl_format_type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (glTextureBufferRangeEXT == nullptr)
|
||||
throw EXCEPTION("OpenGL error: partial buffer access for textures is unsupported on your system");
|
||||
|
||||
__glcheck glTextureBufferRangeEXT(id(), (GLenum)target::textureBuffer, gl_format_type, buf.id(), offset, length);
|
||||
}
|
||||
|
||||
void copy_from(buffer &buf, u32 gl_format_type)
|
||||
{
|
||||
save_binding_state save(*this);
|
||||
__glcheck glTexBuffer((GLenum)target::textureBuffer, gl_format_type, buf.id());
|
||||
}
|
||||
|
||||
void copy_from(const buffer& buf, texture::format format, texture::type type, class pixel_unpack_settings pixel_settings)
|
||||
{
|
||||
buffer::save_binding_state save_buffer(buffer::target::pixel_unpack, buf);
|
||||
@@ -1380,7 +1405,7 @@ namespace gl
|
||||
settings& border_color(color4f value);
|
||||
};
|
||||
|
||||
GLenum draw_mode(Primitive_type in);
|
||||
GLenum draw_mode(rsx::primitive_type in);
|
||||
|
||||
enum class indices_type
|
||||
{
|
||||
@@ -1523,20 +1548,20 @@ namespace gl
|
||||
void draw_buffer(const attachment& buffer) const;
|
||||
void draw_buffers(const std::initializer_list<attachment>& indexes) const;
|
||||
|
||||
void draw_arrays(Primitive_type mode, GLsizei count, GLint first = 0) const;
|
||||
void draw_arrays(const buffer& buffer, Primitive_type mode, GLsizei count, GLint first = 0) const;
|
||||
void draw_arrays(const vao& buffer, Primitive_type mode, GLsizei count, GLint first = 0) const;
|
||||
void draw_arrays(rsx::primitive_type mode, GLsizei count, GLint first = 0) const;
|
||||
void draw_arrays(const buffer& buffer, rsx::primitive_type mode, GLsizei count, GLint first = 0) const;
|
||||
void draw_arrays(const vao& buffer, rsx::primitive_type mode, GLsizei count, GLint first = 0) const;
|
||||
|
||||
void draw_elements(Primitive_type mode, GLsizei count, indices_type type, const GLvoid *indices) const;
|
||||
void draw_elements(const buffer& buffer, Primitive_type mode, GLsizei count, indices_type type, const GLvoid *indices) const;
|
||||
void draw_elements(Primitive_type mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset = 0) const;
|
||||
void draw_elements(const buffer& buffer_, Primitive_type mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset = 0) const;
|
||||
void draw_elements(Primitive_type mode, GLsizei count, const GLubyte *indices) const;
|
||||
void draw_elements(const buffer& buffer, Primitive_type mode, GLsizei count, const GLubyte *indices) const;
|
||||
void draw_elements(Primitive_type mode, GLsizei count, const GLushort *indices) const;
|
||||
void draw_elements(const buffer& buffer, Primitive_type mode, GLsizei count, const GLushort *indices) const;
|
||||
void draw_elements(Primitive_type mode, GLsizei count, const GLuint *indices) const;
|
||||
void draw_elements(const buffer& buffer, Primitive_type mode, GLsizei count, const GLuint *indices) const;
|
||||
void draw_elements(rsx::primitive_type mode, GLsizei count, indices_type type, const GLvoid *indices) const;
|
||||
void draw_elements(const buffer& buffer, rsx::primitive_type mode, GLsizei count, indices_type type, const GLvoid *indices) const;
|
||||
void draw_elements(rsx::primitive_type mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset = 0) const;
|
||||
void draw_elements(const buffer& buffer_, rsx::primitive_type mode, GLsizei count, indices_type type, const buffer& indices, size_t indices_buffer_offset = 0) const;
|
||||
void draw_elements(rsx::primitive_type mode, GLsizei count, const GLubyte *indices) const;
|
||||
void draw_elements(const buffer& buffer, rsx::primitive_type mode, GLsizei count, const GLubyte *indices) const;
|
||||
void draw_elements(rsx::primitive_type mode, GLsizei count, const GLushort *indices) const;
|
||||
void draw_elements(const buffer& buffer, rsx::primitive_type mode, GLsizei count, const GLushort *indices) const;
|
||||
void draw_elements(rsx::primitive_type mode, GLsizei count, const GLuint *indices) const;
|
||||
void draw_elements(const buffer& buffer, rsx::primitive_type mode, GLsizei count, const GLuint *indices) const;
|
||||
|
||||
void clear(buffers buffers_) const;
|
||||
void clear(buffers buffers_, color4f color_value, double depth_value, u8 stencil_value) const;
|
||||
@@ -2071,7 +2096,6 @@ namespace gl
|
||||
void make()
|
||||
{
|
||||
link();
|
||||
validate();
|
||||
}
|
||||
|
||||
uint id() const
|
||||
|
||||
+136
-160
@@ -5,6 +5,7 @@
|
||||
#include "../RSXThread.h"
|
||||
#include "../RSXTexture.h"
|
||||
#include "../rsx_utils.h"
|
||||
#include "../Common/TextureUtils.h"
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
@@ -89,6 +90,63 @@ namespace rsx
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
u16 texture::get_pitch_modifier(u32 format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_HILO8:
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8:
|
||||
default:
|
||||
LOG_ERROR(RSX, "Unimplemented Texture format : 0x%x", format);
|
||||
return 0;
|
||||
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8:
|
||||
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
|
||||
return 4;
|
||||
case CELL_GCM_TEXTURE_B8:
|
||||
return 1;
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_DXT1:
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_DXT23:
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_DXT45:
|
||||
return 0;
|
||||
case CELL_GCM_TEXTURE_A1R5G5B5:
|
||||
case CELL_GCM_TEXTURE_A4R4G4B4:
|
||||
case CELL_GCM_TEXTURE_R5G6B5:
|
||||
case CELL_GCM_TEXTURE_G8B8:
|
||||
case CELL_GCM_TEXTURE_R6G5B5:
|
||||
case CELL_GCM_TEXTURE_DEPTH16:
|
||||
case CELL_GCM_TEXTURE_DEPTH16_FLOAT:
|
||||
case CELL_GCM_TEXTURE_X16:
|
||||
case CELL_GCM_TEXTURE_R5G5B5A1:
|
||||
case CELL_GCM_TEXTURE_D1R5G5B5:
|
||||
return 2;
|
||||
case CELL_GCM_TEXTURE_A8R8G8B8:
|
||||
case CELL_GCM_TEXTURE_X32_FLOAT:
|
||||
case CELL_GCM_TEXTURE_Y16_X16_FLOAT:
|
||||
case CELL_GCM_TEXTURE_D8R8G8B8:
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8:
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
|
||||
case CELL_GCM_TEXTURE_DEPTH24_D8:
|
||||
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT:
|
||||
case CELL_GCM_TEXTURE_Y16_X16:
|
||||
return 4;
|
||||
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
|
||||
return 8;
|
||||
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT:
|
||||
return 16;
|
||||
}
|
||||
}
|
||||
|
||||
bool texture::mandates_expansion(u32 format)
|
||||
{
|
||||
/**
|
||||
* If a texture behaves differently when uploaded directly vs when uploaded via texutils methods, it should be added here.
|
||||
*/
|
||||
if (format == CELL_GCM_TEXTURE_A1R5G5B5)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void texture::init(int index, rsx::texture& tex)
|
||||
{
|
||||
if (!m_id)
|
||||
@@ -110,8 +168,6 @@ namespace rsx
|
||||
u32 format = full_format & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
bool is_swizzled = !!(~full_format & CELL_GCM_TEXTURE_LN);
|
||||
|
||||
const u8* pixels = vm::ps3::_ptr<u8>(texaddr);
|
||||
u8 *unswizzledPixels;
|
||||
static const GLint glRemapStandard[4] = { GL_ALPHA, GL_RED, GL_GREEN, GL_BLUE };
|
||||
// NOTE: This must be in ARGB order in all forms below.
|
||||
const GLint *glRemap = glRemapStandard;
|
||||
@@ -119,14 +175,36 @@ namespace rsx
|
||||
::gl::pixel_pack_settings().apply();
|
||||
::gl::pixel_unpack_settings().apply();
|
||||
|
||||
u32 pitch = tex.pitch();
|
||||
u32 aligned_pitch = tex.pitch();
|
||||
|
||||
size_t texture_data_sz = get_placed_texture_storage_size(tex, 256);
|
||||
std::vector<u8> data_upload_buf(texture_data_sz);
|
||||
u8* texture_data = data_upload_buf.data();
|
||||
u32 block_sz = get_pitch_modifier(format);
|
||||
|
||||
if (is_swizzled || mandates_expansion(format))
|
||||
{
|
||||
aligned_pitch = align(aligned_pitch, 256);
|
||||
upload_placed_texture(tex, 256, texture_data);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
texture_data = vm::ps3::_ptr<u8>(texaddr);
|
||||
}
|
||||
|
||||
if (block_sz)
|
||||
aligned_pitch /= block_sz;
|
||||
else
|
||||
aligned_pitch = 0;
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, aligned_pitch);
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case CELL_GCM_TEXTURE_B8: // One 8-bit fixed-point number
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BLUE, GL_UNSIGNED_BYTE, texture_data);
|
||||
|
||||
static const GLint swizzleMaskB8[] = { GL_BLUE, GL_BLUE, GL_BLUE, GL_BLUE };
|
||||
glRemap = swizzleMaskB8;
|
||||
@@ -135,19 +213,13 @@ namespace rsx
|
||||
|
||||
case CELL_GCM_TEXTURE_A1R5G5B5:
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 2);
|
||||
|
||||
// TODO: texture swizzling
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels);
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, texture_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_A4R4G4B4:
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 2);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4, texture_data);
|
||||
|
||||
// We read it in as R4G4B4A4, so we need to remap each component.
|
||||
static const GLint swizzleMaskA4R4G4B4[] = { GL_BLUE, GL_ALPHA, GL_RED, GL_GREEN };
|
||||
@@ -157,67 +229,43 @@ namespace rsx
|
||||
|
||||
case CELL_GCM_TEXTURE_R5G6B5:
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 2);
|
||||
LOG_WARNING(RSX, "CELL_GCM_R5G6B5 texture. Watch out for corruption due to swapped color channels!");
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex.width(), tex.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGB, tex.width(), tex.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, texture_data);
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_A8R8G8B8:
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 4);
|
||||
|
||||
if (is_swizzled)
|
||||
{
|
||||
u32 *src, *dst;
|
||||
u16 height = tex.height();
|
||||
u16 width = tex.width();
|
||||
|
||||
unswizzledPixels = (u8*)malloc(width * height * 4);
|
||||
src = (u32*)pixels;
|
||||
dst = (u32*)unswizzledPixels;
|
||||
|
||||
if ((height & (height - 1)) || (width & (width - 1)))
|
||||
{
|
||||
LOG_ERROR(RSX, "Swizzle Texture: Width or height not power of 2! (h=%d,w=%d).", height, width);
|
||||
}
|
||||
|
||||
rsx::convert_linear_swizzle<u32>(src, dst, width, height, true);
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, is_swizzled ? unswizzledPixels : pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, texture_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_DXT1: // Compressed 4x4 pixels into 8 bytes
|
||||
{
|
||||
u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 8;
|
||||
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.width(), tex.height(), 0, size, pixels);
|
||||
glCompressedTexImage2D(m_target, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.width(), tex.height(), 0, size, texture_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_DXT23: // Compressed 4x4 pixels into 16 bytes
|
||||
{
|
||||
u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 16;
|
||||
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.width(), tex.height(), 0, size, pixels);
|
||||
glCompressedTexImage2D(m_target, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.width(), tex.height(), 0, size, texture_data);
|
||||
}
|
||||
break;
|
||||
|
||||
case CELL_GCM_TEXTURE_COMPRESSED_DXT45: // Compressed 4x4 pixels into 16 bytes
|
||||
{
|
||||
u32 size = ((tex.width() + 3) / 4) * ((tex.height() + 3) / 4) * 16;
|
||||
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.width(), tex.height(), 0, size, pixels);
|
||||
glCompressedTexImage2D(m_target, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.width(), tex.height(), 0, size, texture_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_G8B8:
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 2);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_BYTE, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_BYTE, texture_data);
|
||||
|
||||
static const GLint swizzleMaskG8B8[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN };
|
||||
glRemap = swizzleMaskG8B8;
|
||||
@@ -226,60 +274,39 @@ namespace rsx
|
||||
|
||||
case CELL_GCM_TEXTURE_R6G5B5:
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 2);
|
||||
|
||||
// TODO: Probably need to actually unswizzle if is_swizzled.
|
||||
const u32 numPixels = tex.width() * tex.height();
|
||||
unswizzledPixels = (u8 *)malloc(numPixels * 4);
|
||||
// TODO: Speed.
|
||||
for (u32 i = 0; i < numPixels; ++i) {
|
||||
u16 c = reinterpret_cast<const be_t<u16> *>(pixels)[i];
|
||||
unswizzledPixels[i * 4 + 0] = convert_6_to_8((c >> 10) & 0x3F);
|
||||
unswizzledPixels[i * 4 + 1] = convert_5_to_8((c >> 5) & 0x1F);
|
||||
unswizzledPixels[i * 4 + 2] = convert_5_to_8((c >> 0) & 0x1F);
|
||||
unswizzledPixels[i * 4 + 3] = 255;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels);
|
||||
|
||||
free(unswizzledPixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_DEPTH24_D8: // 24-bit unsigned fixed-point number and 8 bits of garbage
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 4);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, pixels);
|
||||
glTexImage2D(m_target, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, texture_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // 24-bit unsigned float and 8 bits of garbage
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 4);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels);
|
||||
glTexImage2D(m_target, 0, GL_DEPTH_COMPONENT24, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, texture_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_DEPTH16: // 16-bit unsigned fixed-point number
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 2);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_SHORT, pixels);
|
||||
glTexImage2D(m_target, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_SHORT, texture_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // 16-bit unsigned float
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 2);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, pixels);
|
||||
glTexImage2D(m_target, 0, GL_DEPTH_COMPONENT16, tex.width(), tex.height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, texture_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_X16: // A 16-bit fixed-point number
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 2);
|
||||
LOG_WARNING(RSX, "CELL_GCM_X16 texture. Watch out for corruption due to swapped color channels!");
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_UNSIGNED_SHORT, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_UNSIGNED_SHORT, texture_data);
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
|
||||
static const GLint swizzleMaskX16[] = { GL_RED, GL_ONE, GL_RED, GL_ONE };
|
||||
@@ -289,10 +316,11 @@ namespace rsx
|
||||
|
||||
case CELL_GCM_TEXTURE_Y16_X16: // Two 16-bit fixed-point numbers
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 4);
|
||||
LOG_WARNING(RSX, "CELL_GCM_Y16_X16 texture. Watch out for corruption due to swapped color channels!");
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_SHORT, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_UNSIGNED_SHORT, texture_data);
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
|
||||
static const GLint swizzleMaskX32_Y16_X16[] = { GL_GREEN, GL_RED, GL_GREEN, GL_RED };
|
||||
glRemap = swizzleMaskX32_Y16_X16;
|
||||
break;
|
||||
@@ -300,35 +328,34 @@ namespace rsx
|
||||
|
||||
case CELL_GCM_TEXTURE_R5G5B5A1:
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 2);
|
||||
LOG_WARNING(RSX, "CELL_GCM_R5G6B5A1 texture. Watch out for corruption due to swapped color channels!");
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, texture_data);
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: // Four fp16 values
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 8);
|
||||
LOG_WARNING(RSX, "CELL_GCM_W16_Z16_Y16_X16_FLOAT texture. Watch out for corruption due to swapped color channels!");
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_HALF_FLOAT, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_HALF_FLOAT, texture_data);
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: // Four fp32 values
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 16);
|
||||
LOG_WARNING(RSX, "CELL_GCM_W32_Z32_Y32_X32_FLOAT texture. Watch out for corruption due to swapped color channels!");
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_FLOAT, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_FLOAT, texture_data);
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
case CELL_GCM_TEXTURE_X32_FLOAT: // One 32-bit floating-point number
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 4);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_FLOAT, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RED, GL_FLOAT, texture_data);
|
||||
|
||||
static const GLint swizzleMaskX32_FLOAT[] = { GL_RED, GL_ONE, GL_ONE, GL_ONE };
|
||||
glRemap = swizzleMaskX32_FLOAT;
|
||||
@@ -337,11 +364,11 @@ namespace rsx
|
||||
|
||||
case CELL_GCM_TEXTURE_D1R5G5B5:
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 2);
|
||||
LOG_WARNING(RSX, "CELL_GCM_D1R5G5B5 texture. Watch out for corruption due to swapped color channels!");
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
|
||||
|
||||
// TODO: Texture swizzling
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, texture_data);
|
||||
|
||||
static const GLint swizzleMaskX32_D1R5G5B5[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE };
|
||||
glRemap = swizzleMaskX32_D1R5G5B5;
|
||||
@@ -352,8 +379,7 @@ namespace rsx
|
||||
|
||||
case CELL_GCM_TEXTURE_D8R8G8B8: // 8 bits of garbage and three unsigned 8-bit fixed-point numbers
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 4);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, texture_data);
|
||||
|
||||
static const GLint swizzleMaskX32_D8R8G8B8[] = { GL_ONE, GL_RED, GL_GREEN, GL_BLUE };
|
||||
glRemap = swizzleMaskX32_D8R8G8B8;
|
||||
@@ -363,9 +389,9 @@ namespace rsx
|
||||
|
||||
case CELL_GCM_TEXTURE_Y16_X16_FLOAT: // Two fp16 values
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 4);
|
||||
LOG_WARNING(RSX, "CELL_GCM_Y16_X16_FLOAT texture. Watch out for corruption due to swapped color channels!");
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_HALF_FLOAT, pixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RG, GL_HALF_FLOAT, texture_data);
|
||||
glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
|
||||
|
||||
static const GLint swizzleMaskX32_Y16_X16_FLOAT[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN };
|
||||
@@ -374,54 +400,9 @@ namespace rsx
|
||||
}
|
||||
|
||||
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8:
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 4);
|
||||
|
||||
const u32 numPixels = tex.width() * tex.height();
|
||||
unswizzledPixels = (u8 *)malloc(numPixels * 4);
|
||||
// TODO: Speed.
|
||||
for (u32 i = 0; i < numPixels; i += 2)
|
||||
{
|
||||
unswizzledPixels[i * 4 + 0 + 0] = pixels[i * 2 + 3];
|
||||
unswizzledPixels[i * 4 + 0 + 1] = pixels[i * 2 + 2];
|
||||
unswizzledPixels[i * 4 + 0 + 2] = pixels[i * 2 + 0];
|
||||
unswizzledPixels[i * 4 + 0 + 3] = 255;
|
||||
|
||||
// The second pixel is the same, except for red.
|
||||
unswizzledPixels[i * 4 + 4 + 0] = pixels[i * 2 + 1];
|
||||
unswizzledPixels[i * 4 + 4 + 1] = pixels[i * 2 + 2];
|
||||
unswizzledPixels[i * 4 + 4 + 2] = pixels[i * 2 + 0];
|
||||
unswizzledPixels[i * 4 + 4 + 3] = 255;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels);
|
||||
free(unswizzledPixels);
|
||||
break;
|
||||
}
|
||||
|
||||
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / 4);
|
||||
|
||||
const u32 numPixels = tex.width() * tex.height();
|
||||
unswizzledPixels = (u8 *)malloc(numPixels * 4);
|
||||
// TODO: Speed.
|
||||
for (u32 i = 0; i < numPixels; i += 2)
|
||||
{
|
||||
unswizzledPixels[i * 4 + 0 + 0] = pixels[i * 2 + 2];
|
||||
unswizzledPixels[i * 4 + 0 + 1] = pixels[i * 2 + 3];
|
||||
unswizzledPixels[i * 4 + 0 + 2] = pixels[i * 2 + 1];
|
||||
unswizzledPixels[i * 4 + 0 + 3] = 255;
|
||||
|
||||
// The second pixel is the same, except for red.
|
||||
unswizzledPixels[i * 4 + 4 + 0] = pixels[i * 2 + 0];
|
||||
unswizzledPixels[i * 4 + 4 + 1] = pixels[i * 2 + 3];
|
||||
unswizzledPixels[i * 4 + 4 + 2] = pixels[i * 2 + 1];
|
||||
unswizzledPixels[i * 4 + 4 + 3] = 255;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, unswizzledPixels);
|
||||
free(unswizzledPixels);
|
||||
glTexImage2D(m_target, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -432,8 +413,8 @@ namespace rsx
|
||||
}
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.mipmap() - 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.mipmap() > 1);
|
||||
glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, tex.mipmap() - 1);
|
||||
glTexParameteri(m_target, GL_GENERATE_MIPMAP, tex.mipmap() > 1);
|
||||
|
||||
if (format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16 && format != CELL_GCM_TEXTURE_X32_FLOAT)
|
||||
{
|
||||
@@ -442,48 +423,43 @@ namespace rsx
|
||||
u8 remap_g = (tex.remap() >> 4) & 0x3;
|
||||
u8 remap_b = (tex.remap() >> 6) & 0x3;
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, glRemap[remap_a]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, glRemap[remap_r]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, glRemap[remap_g]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, glRemap[remap_b]);
|
||||
glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_A, glRemap[remap_a]);
|
||||
glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_R, glRemap[remap_r]);
|
||||
glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_G, glRemap[remap_g]);
|
||||
glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_B, glRemap[remap_b]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, glRemap[0]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, glRemap[1]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, glRemap[2]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, glRemap[3]);
|
||||
glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_A, glRemap[0]);
|
||||
glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_R, glRemap[1]);
|
||||
glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_G, glRemap[2]);
|
||||
glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_B, glRemap[3]);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl_wrap(tex.wrap_s()));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl_wrap(tex.wrap_t()));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, gl_wrap(tex.wrap_r()));
|
||||
glTexParameteri(m_target, GL_TEXTURE_WRAP_S, gl_wrap(tex.wrap_s()));
|
||||
glTexParameteri(m_target, GL_TEXTURE_WRAP_T, gl_wrap(tex.wrap_t()));
|
||||
glTexParameteri(m_target, GL_TEXTURE_WRAP_R, gl_wrap(tex.wrap_r()));
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.zfunc()]);
|
||||
glTexParameteri(m_target, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.zfunc()]);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, (GLint)tex.bias());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8));
|
||||
glTexParameteri(m_target, GL_TEXTURE_MIN_LOD, (tex.min_lod() >> 8));
|
||||
glTexParameteri(m_target, GL_TEXTURE_MAX_LOD, (tex.max_lod() >> 8));
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_min_filter[tex.min_filter()]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.mag_filter()]);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso()));
|
||||
|
||||
if (is_swizzled && format == CELL_GCM_TEXTURE_A8R8G8B8)
|
||||
{
|
||||
free(unswizzledPixels);
|
||||
}
|
||||
glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, gl_tex_min_filter[tex.min_filter()]);
|
||||
glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, gl_tex_mag_filter[tex.mag_filter()]);
|
||||
glTexParameterf(m_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_aniso(tex.max_aniso()));
|
||||
}
|
||||
|
||||
void texture::bind()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, m_id);
|
||||
glBindTexture(m_target, m_id);
|
||||
}
|
||||
|
||||
void texture::unbind()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(m_target, 0);
|
||||
}
|
||||
|
||||
void texture::remove()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "OpenGL.h"
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
@@ -8,6 +9,7 @@ namespace rsx
|
||||
class texture
|
||||
{
|
||||
u32 m_id = 0;
|
||||
u32 m_target = GL_TEXTURE_2D;
|
||||
|
||||
public:
|
||||
void create();
|
||||
@@ -35,10 +37,25 @@ namespace rsx
|
||||
}
|
||||
|
||||
void init(int index, rsx::texture& tex);
|
||||
|
||||
/**
|
||||
* If a format is marked as mandating expansion, any request to have the data uploaded to the GPU shall require that the pixel data
|
||||
* be decoded/expanded fully, regardless of whether the input is swizzled. This is because some formats behave differently when swizzled pixel data
|
||||
* is decoded and when data is fed directly, usually byte order is not the same. Forcing decoding/expanding fixes this but slows performance.
|
||||
*/
|
||||
static bool mandates_expansion(u32 format);
|
||||
|
||||
/**
|
||||
* The pitch modifier changes the pitch value supplied by the rsx::texture by supplying a suitable divisor or 0 if no change is needed.
|
||||
* The modified value, if any, is then used to supply to GL the UNPACK_ROW_LENGTH for the texture data to be supplied.
|
||||
*/
|
||||
static u16 get_pitch_modifier(u32 format);
|
||||
|
||||
void bind();
|
||||
void unbind();
|
||||
void remove();
|
||||
|
||||
void set_target(u32 target) { m_target = target; }
|
||||
u32 id() const;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "GCM.h"
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -204,26 +205,54 @@ static const std::string rsx_fp_op_names[] =
|
||||
"NULL", "BRK", "CAL", "IFE", "LOOP", "REP", "RET"
|
||||
};
|
||||
|
||||
enum class texture_dimension
|
||||
enum class texture_dimension : u8
|
||||
{
|
||||
texture_dimension_2d,
|
||||
texture_dimension_2d_array,
|
||||
texture_dimension_cubemap,
|
||||
texture_dimension_1d = 0,
|
||||
texture_dimension_2d = 1,
|
||||
texture_dimension_cubemap = 2,
|
||||
texture_dimension_3d = 3,
|
||||
};
|
||||
|
||||
struct RSXFragmentProgram
|
||||
{
|
||||
u32 size;
|
||||
u32 addr;
|
||||
void *addr;
|
||||
u32 offset;
|
||||
u32 ctrl;
|
||||
std::vector<texture_dimension> texture_dimensions;
|
||||
u16 unnormalized_coords;
|
||||
rsx::comparaison_function alpha_func;
|
||||
bool front_back_color_enabled : 1;
|
||||
bool back_color_diffuse_output : 1;
|
||||
bool back_color_specular_output : 1;
|
||||
u32 texture_dimensions;
|
||||
rsx::window_origin origin_mode;
|
||||
rsx::window_pixel_center pixel_center_mode;
|
||||
u16 height;
|
||||
|
||||
texture_dimension get_texture_dimension(u8 id) const
|
||||
{
|
||||
return (texture_dimension)((texture_dimensions >> (id * 2)) & 0x3);
|
||||
}
|
||||
|
||||
void set_texture_dimension(const std::array<texture_dimension, 16> &dimensions)
|
||||
{
|
||||
size_t id = 0;
|
||||
for (const texture_dimension &dim : dimensions)
|
||||
{
|
||||
texture_dimensions &= ~(0x3 << (id * 2));
|
||||
u8 d = (u8)dim;
|
||||
texture_dimensions |= ((d & 0x3) << (id * 2));
|
||||
id++;
|
||||
}
|
||||
}
|
||||
|
||||
RSXFragmentProgram()
|
||||
: size(0)
|
||||
, addr(0)
|
||||
, offset(0)
|
||||
, ctrl(0)
|
||||
, unnormalized_coords(0)
|
||||
, texture_dimensions(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -202,12 +202,12 @@ namespace rsx
|
||||
|
||||
u16 texture::depth() const
|
||||
{
|
||||
return method_registers[NV4097_SET_TEXTURE_CONTROL3] >> 20;
|
||||
return method_registers[NV4097_SET_TEXTURE_CONTROL3 + m_index] >> 20;
|
||||
}
|
||||
|
||||
u32 texture::pitch() const
|
||||
{
|
||||
return method_registers[NV4097_SET_TEXTURE_CONTROL3] & 0xfffff;
|
||||
return method_registers[NV4097_SET_TEXTURE_CONTROL3 + m_index] & 0xfffff;
|
||||
}
|
||||
|
||||
void vertex_texture::init(u8 index)
|
||||
@@ -386,11 +386,11 @@ namespace rsx
|
||||
|
||||
u16 vertex_texture::depth() const
|
||||
{
|
||||
return method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL3] >> 20;
|
||||
return method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL3 + (m_index * 8)] >> 20;
|
||||
}
|
||||
|
||||
u32 vertex_texture::pitch() const
|
||||
{
|
||||
return method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL3] & 0xfffff;
|
||||
return method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL3 + (m_index * 8)] & 0xfffff;
|
||||
}
|
||||
}
|
||||
+178
-13
@@ -19,6 +19,8 @@ frame_capture_data frame_debug;
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
std::function<bool(u32 addr, bool is_writing)> g_access_violation_handler;
|
||||
|
||||
std::string shaders_cache::path_to_root()
|
||||
{
|
||||
return fs::get_executable_dir() + "data/";
|
||||
@@ -120,11 +122,11 @@ namespace rsx
|
||||
return res;
|
||||
}
|
||||
|
||||
u32 get_vertex_type_size_on_host(Vertex_base_type type, u32 size)
|
||||
u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Vertex_base_type::s1:
|
||||
case vertex_base_type::s1:
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
@@ -135,8 +137,8 @@ namespace rsx
|
||||
return sizeof(u16) * 4;
|
||||
}
|
||||
throw new EXCEPTION("Wrong vector size");
|
||||
case Vertex_base_type::f: return sizeof(f32) * size;
|
||||
case Vertex_base_type::sf:
|
||||
case vertex_base_type::f: return sizeof(f32) * size;
|
||||
case vertex_base_type::sf:
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
@@ -147,7 +149,7 @@ namespace rsx
|
||||
return sizeof(f16) * 4;
|
||||
}
|
||||
throw new EXCEPTION("Wrong vector size");
|
||||
case Vertex_base_type::ub:
|
||||
case vertex_base_type::ub:
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
@@ -158,16 +160,16 @@ namespace rsx
|
||||
return sizeof(u8) * 4;
|
||||
}
|
||||
throw new EXCEPTION("Wrong vector size");
|
||||
case Vertex_base_type::s32k: return sizeof(u32) * size;
|
||||
case Vertex_base_type::cmp: return sizeof(u16) * 4;
|
||||
case Vertex_base_type::ub256: return sizeof(u8) * 4;
|
||||
case vertex_base_type::s32k: return sizeof(u32) * size;
|
||||
case vertex_base_type::cmp: return sizeof(u16) * 4;
|
||||
case vertex_base_type::ub256: return sizeof(u8) * 4;
|
||||
|
||||
default:
|
||||
throw new EXCEPTION("RSXVertexData::GetTypeSize: Bad vertex data type (%d)!", type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tiled_region::write(const void *src, u32 width, u32 height, u32 pitch)
|
||||
{
|
||||
if (!tile)
|
||||
@@ -270,6 +272,21 @@ namespace rsx
|
||||
}
|
||||
}
|
||||
|
||||
thread::thread()
|
||||
{
|
||||
g_access_violation_handler = [this](u32 address, bool is_writing)
|
||||
{
|
||||
return on_access_violation(address, is_writing);
|
||||
};
|
||||
m_rtts_dirty = true;
|
||||
memset(m_textures_dirty, -1, sizeof(m_textures_dirty));
|
||||
}
|
||||
|
||||
thread::~thread()
|
||||
{
|
||||
g_access_violation_handler = nullptr;
|
||||
}
|
||||
|
||||
void thread::capture_frame(const std::string &name)
|
||||
{
|
||||
frame_capture_data::draw_state draw_state = {};
|
||||
@@ -280,9 +297,9 @@ namespace rsx
|
||||
surface.unpack(rsx::method_registers[NV4097_SET_SURFACE_FORMAT]);
|
||||
draw_state.width = clip_w;
|
||||
draw_state.height = clip_h;
|
||||
draw_state.surface_color_format = surface.color_format;
|
||||
draw_state.color_format = surface.color_format;
|
||||
draw_state.color_buffer = std::move(copy_render_targets_to_memory());
|
||||
draw_state.surface_depth_format = surface.depth_format;
|
||||
draw_state.depth_format = surface.depth_format;
|
||||
draw_state.depth_stencil = std::move(copy_depth_stencil_buffer_to_memory());
|
||||
draw_state.programs = get_programs();
|
||||
draw_state.name = name;
|
||||
@@ -354,7 +371,7 @@ namespace rsx
|
||||
|
||||
if (put == get || !Emu.IsRunning())
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
do_internal_task();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -483,7 +500,7 @@ namespace rsx
|
||||
|
||||
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
|
||||
|
||||
if (info.type == Vertex_base_type::ub && info.size == 4)
|
||||
if (info.type == vertex_base_type::ub && info.size == 4)
|
||||
{
|
||||
dst[0] = src[3];
|
||||
dst[1] = src[2];
|
||||
@@ -507,6 +524,52 @@ namespace rsx
|
||||
return get_system_time() * 1000;
|
||||
}
|
||||
|
||||
void thread::do_internal_task()
|
||||
{
|
||||
if (m_internal_tasks.empty())
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::lock_guard<std::mutex> lock{ m_mtx_task };
|
||||
|
||||
internal_task_entry &front = m_internal_tasks.front();
|
||||
|
||||
if (front.callback())
|
||||
{
|
||||
front.promise.set_value();
|
||||
m_internal_tasks.pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::future<void> thread::add_internal_task(std::function<bool()> callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock{ m_mtx_task };
|
||||
m_internal_tasks.emplace_back(callback);
|
||||
|
||||
return m_internal_tasks.back().promise.get_future();
|
||||
}
|
||||
|
||||
void thread::invoke(std::function<bool()> callback)
|
||||
{
|
||||
if (get_thread_ctrl() == thread_ctrl::get_current())
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (callback())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
add_internal_task(callback).wait();
|
||||
}
|
||||
}
|
||||
|
||||
std::array<u32, 4> thread::get_color_surface_addresses() const
|
||||
{
|
||||
u32 offset_color[] =
|
||||
@@ -539,6 +602,106 @@ namespace rsx
|
||||
return rsx::get_address(offset_zeta, m_context_dma_z);
|
||||
}
|
||||
|
||||
RSXVertexProgram thread::get_current_vertex_program() const
|
||||
{
|
||||
RSXVertexProgram result = {};
|
||||
u32 transform_program_start = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START];
|
||||
result.data.reserve((512 - transform_program_start) * 4);
|
||||
|
||||
for (int i = transform_program_start; i < 512; ++i)
|
||||
{
|
||||
result.data.resize((i - transform_program_start) * 4 + 4);
|
||||
memcpy(result.data.data() + (i - transform_program_start) * 4, transform_program + i * 4, 4 * sizeof(u32));
|
||||
|
||||
D3 d3;
|
||||
d3.HEX = transform_program[i * 4 + 3];
|
||||
|
||||
if (d3.end)
|
||||
break;
|
||||
}
|
||||
result.output_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK];
|
||||
|
||||
u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK];
|
||||
u32 modulo_mask = rsx::method_registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION];
|
||||
result.rsx_vertex_inputs.clear();
|
||||
for (u8 index = 0; index < rsx::limits::vertex_count; ++index)
|
||||
{
|
||||
bool enabled = !!(input_mask & (1 << index));
|
||||
if (!enabled)
|
||||
continue;
|
||||
|
||||
if (vertex_arrays_info[index].size > 0)
|
||||
{
|
||||
result.rsx_vertex_inputs.push_back(
|
||||
{
|
||||
index,
|
||||
vertex_arrays_info[index].size,
|
||||
vertex_arrays_info[index].frequency,
|
||||
!!((modulo_mask >> index) & 0x1),
|
||||
true
|
||||
}
|
||||
);
|
||||
}
|
||||
else if (register_vertex_info[index].size > 0)
|
||||
{
|
||||
result.rsx_vertex_inputs.push_back(
|
||||
{
|
||||
index,
|
||||
register_vertex_info[index].size,
|
||||
register_vertex_info[index].frequency,
|
||||
!!((modulo_mask >> index) & 0x1),
|
||||
false
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
RSXFragmentProgram thread::get_current_fragment_program() const
|
||||
{
|
||||
RSXFragmentProgram result = {};
|
||||
u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM];
|
||||
result.offset = shader_program & ~0x3;
|
||||
result.addr = vm::base(rsx::get_address(result.offset, (shader_program & 0x3) - 1));
|
||||
result.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL];
|
||||
result.unnormalized_coords = 0;
|
||||
result.front_back_color_enabled = !rsx::method_registers[NV4097_SET_TWO_SIDE_LIGHT_EN];
|
||||
result.back_color_diffuse_output = !!(rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK] & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE);
|
||||
result.back_color_specular_output = !!(rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK] & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR);
|
||||
result.alpha_func = to_comparaison_function(rsx::method_registers[NV4097_SET_ALPHA_FUNC]);
|
||||
u32 shader_window = rsx::method_registers[NV4097_SET_SHADER_WINDOW];
|
||||
result.origin_mode = rsx::to_window_origin((shader_window >> 12) & 0xF);
|
||||
result.pixel_center_mode = rsx::to_window_pixel_center((shader_window >> 16) & 0xF);
|
||||
result.height = shader_window & 0xFFF;
|
||||
|
||||
std::array<texture_dimension, 16> texture_dimensions;
|
||||
for (u32 i = 0; i < rsx::limits::textures_count; ++i)
|
||||
{
|
||||
if (!textures[i].enabled())
|
||||
texture_dimensions[i] = texture_dimension::texture_dimension_2d;
|
||||
else if (textures[i].dimension() == 1)
|
||||
texture_dimensions[i] = texture_dimension::texture_dimension_1d;
|
||||
else if (textures[i].dimension() == 2)
|
||||
{
|
||||
if (textures[i].cubemap())
|
||||
texture_dimensions[i] = texture_dimension::texture_dimension_cubemap;
|
||||
else
|
||||
texture_dimensions[i] = texture_dimension::texture_dimension_2d;
|
||||
}
|
||||
else if (textures[i].dimension() == 3)
|
||||
texture_dimensions[i] = texture_dimension::texture_dimension_3d;
|
||||
else
|
||||
throw EXCEPTION("Unable to determine texture dimension");
|
||||
if (textures[i].enabled() && (textures[i].format() & CELL_GCM_TEXTURE_UN))
|
||||
result.unnormalized_coords |= (1 << i);
|
||||
}
|
||||
result.set_texture_dimension(texture_dimensions);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void thread::reset()
|
||||
{
|
||||
//setup method registers
|
||||
@@ -603,6 +766,8 @@ namespace rsx
|
||||
method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffffff;
|
||||
|
||||
method_registers[NV4097_SET_CONTEXT_DMA_REPORT] = CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT;
|
||||
rsx::method_registers[NV4097_SET_TWO_SIDE_LIGHT_EN] = true;
|
||||
rsx::method_registers[NV4097_SET_ALPHA_FUNC] = CELL_GCM_ALWAYS;
|
||||
|
||||
// Reset vertex attrib array
|
||||
for (int i = 0; i < limits::vertex_count; i++)
|
||||
|
||||
+44
-18
@@ -15,15 +15,14 @@ extern u64 get_system_time();
|
||||
|
||||
struct frame_capture_data
|
||||
{
|
||||
|
||||
struct draw_state
|
||||
{
|
||||
std::string name;
|
||||
std::pair<std::string, std::string> programs;
|
||||
size_t width = 0, height = 0;
|
||||
Surface_color_format surface_color_format;
|
||||
rsx::surface_color_format color_format;
|
||||
std::array<std::vector<gsl::byte>, 4> color_buffer;
|
||||
Surface_depth_format surface_depth_format;
|
||||
rsx::surface_depth_format depth_format;
|
||||
std::array<std::vector<gsl::byte>, 2> depth_stencil;
|
||||
};
|
||||
std::vector<std::pair<u32, u32> > command_queue;
|
||||
@@ -145,7 +144,7 @@ namespace rsx
|
||||
static std::string path_to_root();
|
||||
};
|
||||
|
||||
u32 get_vertex_type_size_on_host(Vertex_base_type type, u32 size);
|
||||
u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size);
|
||||
|
||||
u32 get_address(u32 offset, u32 location);
|
||||
|
||||
@@ -164,9 +163,9 @@ namespace rsx
|
||||
{
|
||||
u8 log2height;
|
||||
u8 log2width;
|
||||
Surface_antialiasing antialias;
|
||||
Surface_depth_format depth_format;
|
||||
Surface_color_format color_format;
|
||||
surface_antialiasing antialias;
|
||||
surface_depth_format depth_format;
|
||||
surface_color_format color_format;
|
||||
|
||||
u32 width;
|
||||
u32 height;
|
||||
@@ -192,7 +191,7 @@ namespace rsx
|
||||
u16 frequency = 0;
|
||||
u8 stride = 0;
|
||||
u8 size = 0;
|
||||
Vertex_base_type type = Vertex_base_type::f;
|
||||
vertex_base_type type = vertex_base_type::f;
|
||||
|
||||
void unpack_array(u32 data_array_format)
|
||||
{
|
||||
@@ -203,6 +202,13 @@ namespace rsx
|
||||
}
|
||||
};
|
||||
|
||||
enum class draw_command
|
||||
{
|
||||
array,
|
||||
inlined_array,
|
||||
indexed,
|
||||
};
|
||||
|
||||
class thread : public named_thread_t
|
||||
{
|
||||
protected:
|
||||
@@ -257,6 +263,7 @@ namespace rsx
|
||||
|
||||
bool capture_current_frame = false;
|
||||
void capture_frame(const std::string &name);
|
||||
|
||||
public:
|
||||
u32 ioAddress, ioSize;
|
||||
int flip_status;
|
||||
@@ -272,26 +279,22 @@ namespace rsx
|
||||
u32 ctxt_addr;
|
||||
u32 report_main_addr;
|
||||
u32 label_addr;
|
||||
enum class Draw_command
|
||||
{
|
||||
draw_command_array,
|
||||
draw_command_inlined_array,
|
||||
draw_command_indexed,
|
||||
} draw_command;
|
||||
Primitive_type draw_mode;
|
||||
rsx::draw_command draw_command;
|
||||
primitive_type draw_mode;
|
||||
|
||||
u32 local_mem_addr, main_mem_addr;
|
||||
bool strict_ordering[0x1000];
|
||||
|
||||
|
||||
bool draw_inline_vertex_array;
|
||||
std::vector<u32> inline_vertex_array;
|
||||
|
||||
bool m_rtts_dirty;
|
||||
bool m_textures_dirty[16];
|
||||
protected:
|
||||
std::array<u32, 4> get_color_surface_addresses() const;
|
||||
u32 get_zeta_surface_address() const;
|
||||
|
||||
RSXVertexProgram get_current_vertex_program() const;
|
||||
RSXFragmentProgram get_current_fragment_program() const;
|
||||
public:
|
||||
u32 draw_array_count;
|
||||
u32 draw_array_first;
|
||||
@@ -309,7 +312,8 @@ namespace rsx
|
||||
std::set<u32> m_used_gcm_commands;
|
||||
|
||||
protected:
|
||||
virtual ~thread() {}
|
||||
thread();
|
||||
virtual ~thread();
|
||||
|
||||
virtual void on_task() override;
|
||||
|
||||
@@ -324,6 +328,27 @@ namespace rsx
|
||||
virtual bool do_method(u32 cmd, u32 value) { return false; }
|
||||
virtual void flip(int buffer) = 0;
|
||||
virtual u64 timestamp() const;
|
||||
virtual bool on_access_violation(u32 address, bool is_writing) { return false; }
|
||||
|
||||
private:
|
||||
std::mutex m_mtx_task;
|
||||
|
||||
struct internal_task_entry
|
||||
{
|
||||
std::function<bool()> callback;
|
||||
std::promise<void> promise;
|
||||
|
||||
internal_task_entry(std::function<bool()> callback) : callback(callback)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::deque<internal_task_entry> m_internal_tasks;
|
||||
void do_internal_task();
|
||||
|
||||
public:
|
||||
std::future<void> add_internal_task(std::function<bool()> callback);
|
||||
void invoke(std::function<bool()> callback);
|
||||
|
||||
/**
|
||||
* Fill buffer with 4x4 scale offset matrix.
|
||||
@@ -362,6 +387,7 @@ namespace rsx
|
||||
};
|
||||
|
||||
virtual std::pair<std::string, std::string> get_programs() const { return std::make_pair("", ""); };
|
||||
|
||||
public:
|
||||
void reset();
|
||||
void init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress);
|
||||
|
||||
@@ -14,10 +14,10 @@ namespace rsx
|
||||
rsx_method_t methods[0x10000 >> 2]{};
|
||||
|
||||
template<typename Type> struct vertex_data_type_from_element_type;
|
||||
template<> struct vertex_data_type_from_element_type<float> { static const Vertex_base_type type = Vertex_base_type::f; };
|
||||
template<> struct vertex_data_type_from_element_type<f16> { static const Vertex_base_type type = Vertex_base_type::sf; };
|
||||
template<> struct vertex_data_type_from_element_type<u8> { static const Vertex_base_type type = Vertex_base_type::ub; };
|
||||
template<> struct vertex_data_type_from_element_type<u16> { static const Vertex_base_type type = Vertex_base_type::s1; };
|
||||
template<> struct vertex_data_type_from_element_type<float> { static const vertex_base_type type = vertex_base_type::f; };
|
||||
template<> struct vertex_data_type_from_element_type<f16> { static const vertex_base_type type = vertex_base_type::sf; };
|
||||
template<> struct vertex_data_type_from_element_type<u8> { static const vertex_base_type type = vertex_base_type::ub; };
|
||||
template<> struct vertex_data_type_from_element_type<u16> { static const vertex_base_type type = vertex_base_type::s1; };
|
||||
|
||||
namespace nv406e
|
||||
{
|
||||
@@ -160,7 +160,7 @@ namespace rsx
|
||||
|
||||
force_inline void draw_arrays(thread* rsx, u32 arg)
|
||||
{
|
||||
rsx->draw_command = thread::Draw_command::draw_command_array;
|
||||
rsx->draw_command = rsx::draw_command::array;
|
||||
u32 first = arg & 0xffffff;
|
||||
u32 count = (arg >> 24) + 1;
|
||||
|
||||
@@ -169,7 +169,7 @@ namespace rsx
|
||||
|
||||
force_inline void draw_index_array(thread* rsx, u32 arg)
|
||||
{
|
||||
rsx->draw_command = thread::Draw_command::draw_command_indexed;
|
||||
rsx->draw_command = rsx::draw_command::indexed;
|
||||
u32 first = arg & 0xffffff;
|
||||
u32 count = (arg >> 24) + 1;
|
||||
|
||||
@@ -178,7 +178,7 @@ namespace rsx
|
||||
|
||||
force_inline void draw_inline_array(thread* rsx, u32 arg)
|
||||
{
|
||||
rsx->draw_command = thread::Draw_command::draw_command_inlined_array;
|
||||
rsx->draw_command = rsx::draw_command::inlined_array;
|
||||
rsx->draw_inline_vertex_array = true;
|
||||
rsx->inline_vertex_array.push_back(arg);
|
||||
}
|
||||
@@ -287,6 +287,15 @@ namespace rsx
|
||||
{
|
||||
rsx->m_rtts_dirty = true;
|
||||
}
|
||||
|
||||
template<u32 index>
|
||||
struct set_texture_dirty_bit
|
||||
{
|
||||
force_inline static void impl(thread* rsx, u32 arg)
|
||||
{
|
||||
rsx->m_textures_dirty[index] = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace nv308a
|
||||
@@ -834,6 +843,16 @@ namespace rsx
|
||||
bind<NV4097_SET_CONTEXT_DMA_COLOR_D, nv4097::set_surface_dirty_bit>();
|
||||
bind<NV4097_SET_CONTEXT_DMA_ZETA, nv4097::set_surface_dirty_bit>();
|
||||
bind<NV4097_SET_SURFACE_FORMAT, nv4097::set_surface_dirty_bit>();
|
||||
bind_range<NV4097_SET_TEXTURE_OFFSET, 8, 16, nv4097::set_texture_dirty_bit>();
|
||||
bind_range<NV4097_SET_TEXTURE_FORMAT, 8, 16, nv4097::set_texture_dirty_bit>();
|
||||
bind_range<NV4097_SET_TEXTURE_ADDRESS, 8, 16, nv4097::set_texture_dirty_bit>();
|
||||
bind_range<NV4097_SET_TEXTURE_CONTROL0, 8, 16, nv4097::set_texture_dirty_bit>();
|
||||
bind_range<NV4097_SET_TEXTURE_CONTROL1, 8, 16, nv4097::set_texture_dirty_bit>();
|
||||
bind_range<NV4097_SET_TEXTURE_CONTROL2, 8, 16, nv4097::set_texture_dirty_bit>();
|
||||
bind_range<NV4097_SET_TEXTURE_CONTROL3, 1, 16, nv4097::set_texture_dirty_bit>();
|
||||
bind_range<NV4097_SET_TEXTURE_FILTER, 8, 16, nv4097::set_texture_dirty_bit>();
|
||||
bind_range<NV4097_SET_TEXTURE_IMAGE_RECT, 8, 16, nv4097::set_texture_dirty_bit>();
|
||||
bind_range<NV4097_SET_TEXTURE_BORDER_COLOR, 8, 16, nv4097::set_texture_dirty_bit>();
|
||||
|
||||
//NV308A
|
||||
bind_range<NV308A_COLOR, 1, 256, nv308a::color>();
|
||||
|
||||
@@ -39,8 +39,6 @@ AudioDecoder::AudioDecoder(s32 type, u32 addr, u32 size, vm::ptr<CellAdecCbMsg>
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CELL_ADEC_TYPE_LPCM_PAMF:
|
||||
case CELL_ADEC_TYPE_AC3:
|
||||
case CELL_ADEC_TYPE_ATRACX:
|
||||
case CELL_ADEC_TYPE_ATRACX_2CH:
|
||||
case CELL_ADEC_TYPE_ATRACX_6CH:
|
||||
@@ -51,7 +49,6 @@ AudioDecoder::AudioDecoder(s32 type, u32 addr, u32 size, vm::ptr<CellAdecCbMsg>
|
||||
break;
|
||||
}
|
||||
case CELL_ADEC_TYPE_MP3:
|
||||
case CELL_ADEC_TYPE_MPEG_L2:
|
||||
{
|
||||
codec = avcodec_find_decoder(AV_CODEC_ID_MP3);
|
||||
input_format = av_find_input_format("mp3");
|
||||
@@ -478,16 +475,16 @@ bool adecCheckType(s32 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case CELL_ADEC_TYPE_LPCM_PAMF: cellAdec.notice("adecCheckType(): LPCM pamf"); break;
|
||||
case CELL_ADEC_TYPE_AC3: cellAdec.notice("adecCheckType(): AC3"); break;
|
||||
case CELL_ADEC_TYPE_ATRACX: cellAdec.notice("adecCheckType(): ATRAC3plus"); break;
|
||||
case CELL_ADEC_TYPE_ATRACX_2CH: cellAdec.notice("adecCheckType(): ATRAC3plus 2ch"); break;
|
||||
case CELL_ADEC_TYPE_ATRACX_6CH: cellAdec.notice("adecCheckType(): ATRAC3plus 6ch"); break;
|
||||
case CELL_ADEC_TYPE_ATRACX_8CH: cellAdec.notice("adecCheckType(): ATRAC3plus 8ch"); break;
|
||||
case CELL_ADEC_TYPE_MP3: cellAdec.notice("adecCheckType(): MP3"); break;
|
||||
case CELL_ADEC_TYPE_MPEG_L2: cellAdec.notice("adecCheckType(): Mpeg L2"); break;
|
||||
|
||||
case CELL_ADEC_TYPE_LPCM_PAMF:
|
||||
case CELL_ADEC_TYPE_AC3:
|
||||
case CELL_ADEC_TYPE_ATRAC3:
|
||||
case CELL_ADEC_TYPE_MPEG_L2:
|
||||
case CELL_ADEC_TYPE_CELP:
|
||||
case CELL_ADEC_TYPE_M4AAC:
|
||||
case CELL_ADEC_TYPE_CELP8:
|
||||
@@ -595,8 +592,6 @@ s32 cellAdecStartSeq(u32 handle, u32 param)
|
||||
|
||||
switch (adec->type)
|
||||
{
|
||||
case CELL_ADEC_TYPE_LPCM_PAMF:
|
||||
case CELL_ADEC_TYPE_AC3:
|
||||
case CELL_ADEC_TYPE_ATRACX:
|
||||
case CELL_ADEC_TYPE_ATRACX_2CH:
|
||||
case CELL_ADEC_TYPE_ATRACX_6CH:
|
||||
@@ -617,7 +612,6 @@ s32 cellAdecStartSeq(u32 handle, u32 param)
|
||||
break;
|
||||
}
|
||||
case CELL_ADEC_TYPE_MP3:
|
||||
case CELL_ADEC_TYPE_MPEG_L2:
|
||||
{
|
||||
const auto mp3 = vm::cptr<CellAdecParamMP3>::make(param);
|
||||
|
||||
|
||||
@@ -656,26 +656,26 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor
|
||||
{
|
||||
esAVC[es.fidMajor % 16] = task.es.es_ptr;
|
||||
}
|
||||
else if ((es.fidMajor & -0x10) == 0xe0 && es.fidMinor == 0 && !es.sup1 && !es.sup2)
|
||||
{
|
||||
esM2V[es.fidMajor % 16] = task.es.es_ptr;
|
||||
}
|
||||
//else if ((es.fidMajor & -0x10) == 0xe0 && es.fidMinor == 0 && !es.sup1 && !es.sup2)
|
||||
//{
|
||||
// esM2V[es.fidMajor % 16] = task.es.es_ptr;
|
||||
//}
|
||||
else if (es.fidMajor == 0xbd && (es.fidMinor & -0x10) == 0 && !es.sup1 && !es.sup2)
|
||||
{
|
||||
esATX[es.fidMinor % 16] = task.es.es_ptr;
|
||||
}
|
||||
else if (es.fidMajor == 0xbd && (es.fidMinor & -0x10) == 0x20 && !es.sup1 && !es.sup2)
|
||||
{
|
||||
esDATA[es.fidMinor % 16] = task.es.es_ptr;
|
||||
}
|
||||
else if (es.fidMajor == 0xbd && (es.fidMinor & -0x10) == 0x30 && !es.sup1 && !es.sup2)
|
||||
{
|
||||
esAC3[es.fidMinor % 16] = task.es.es_ptr;
|
||||
}
|
||||
else if (es.fidMajor == 0xbd && (es.fidMinor & -0x10) == 0x40 && !es.sup1 && !es.sup2)
|
||||
{
|
||||
esPCM[es.fidMinor % 16] = task.es.es_ptr;
|
||||
}
|
||||
//else if (es.fidMajor == 0xbd && (es.fidMinor & -0x10) == 0x20 && !es.sup1 && !es.sup2)
|
||||
//{
|
||||
// esDATA[es.fidMinor % 16] = task.es.es_ptr;
|
||||
//}
|
||||
//else if (es.fidMajor == 0xbd && (es.fidMinor & -0x10) == 0x30 && !es.sup1 && !es.sup2)
|
||||
//{
|
||||
// esAC3[es.fidMinor % 16] = task.es.es_ptr;
|
||||
//}
|
||||
//else if (es.fidMajor == 0xbd && (es.fidMinor & -0x10) == 0x40 && !es.sup1 && !es.sup2)
|
||||
//{
|
||||
// esPCM[es.fidMinor % 16] = task.es.es_ptr;
|
||||
//}
|
||||
else
|
||||
{
|
||||
throw EXCEPTION("dmuxEnableEs: unknown filter (0x%x, 0x%x, 0x%x, 0x%x)", es.fidMajor, es.fidMinor, es.sup1, es.sup2);
|
||||
|
||||
@@ -453,7 +453,7 @@ s32 cellFontSetEffectWeight()
|
||||
|
||||
s32 cellFontGlyphSetupVertexesGlyph()
|
||||
{
|
||||
//UNIMPLEMENTED_FUNC(cellFont);
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -478,7 +478,7 @@ s32 cellFontSetScalePoint()
|
||||
s32 cellFontSetupRenderEffectSlant()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
return -1;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellFontGraphicsSetLineRGBA()
|
||||
@@ -508,30 +508,30 @@ s32 cellFontGraphicsSetupDrawContext()
|
||||
s32 cellFontSetupRenderEffectWeight()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
return -1;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellFontGlyphGetOutlineControlDistance()
|
||||
{
|
||||
//UNIMPLEMENTED_FUNC(cellFont);
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellFontGlyphGetVertexesGlyphSize()
|
||||
{
|
||||
//UNIMPLEMENTED_FUNC(cellFont);
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellFontGenerateCharGlyph()
|
||||
{
|
||||
//UNIMPLEMENTED_FUNC(cellFont);
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellFontDeleteGlyph()
|
||||
{
|
||||
//UNIMPLEMENTED_FUNC(cellFont);
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -552,7 +552,7 @@ s32 cellFontExtend(u32 a1, u32 a2, u32 a3)
|
||||
//Something happens
|
||||
}
|
||||
//Something happens?
|
||||
return -1;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellFontRenderCharGlyphImageVertical()
|
||||
@@ -585,14 +585,12 @@ s32 cellFontGraphicsGetDrawType()
|
||||
|
||||
s32 cellFontGetKerning()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
return -1;//throw EXCEPTION("");
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 cellFontGetRenderScaledKerning()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
return -1;//throw EXCEPTION("");
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 cellFontGetRenderScalePixel()
|
||||
@@ -622,8 +620,7 @@ s32 cellFontGetEffectWeight()
|
||||
|
||||
s32 cellFontGetScalePixel()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
return -1;//throw EXCEPTION("");
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 cellFontClearFileCache()
|
||||
@@ -638,8 +635,7 @@ s32 cellFontAdjustFontScaling()
|
||||
|
||||
s32 cellFontSetupRenderScalePoint()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFont);
|
||||
return CELL_OK; //throw EXCEPTION("");
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 cellFontGlyphGetVerticalShift()
|
||||
|
||||
@@ -144,7 +144,7 @@ s32 cellFsFsync(u32 fd)
|
||||
{
|
||||
cellFs.todo("cellFsFsync(fd=0x%x)", fd);
|
||||
|
||||
return -1; //CELL_OK;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellFsFGetBlockSize(u32 fd, vm::ptr<u64> sector_size, vm::ptr<u64> block_size)
|
||||
@@ -987,8 +987,7 @@ s32 cellFsSetIoBufferFromDefaultContainer(u32 fd, u32 buffer_size, u32 page_type
|
||||
|
||||
s32 cellFsUtime()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFs);
|
||||
return CELL_OK;
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 cellFsArcadeHddSerialNumber()
|
||||
@@ -1028,8 +1027,7 @@ s32 cellFsChangeFileSizeWithoutAllocation()
|
||||
|
||||
s32 cellFsAllocateFileAreaWithoutZeroFill()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFs);
|
||||
return CELL_OK;
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 cellFsChangeFileSizeByFdWithoutAllocation()
|
||||
@@ -1039,8 +1037,7 @@ s32 cellFsChangeFileSizeByFdWithoutAllocation()
|
||||
|
||||
s32 cellFsSetDiscReadRetrySetting()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellFs);
|
||||
return CELL_OK;
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 cellFsRegisterConversionCallback()
|
||||
|
||||
@@ -47,7 +47,7 @@ struct content_permission_t final
|
||||
|
||||
s32 cellHddGameCheck(PPUThread& ppu, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellHddGameStatCallback> funcStat, u32 container)
|
||||
{
|
||||
cellGame.warning("cellHddGameCheck(version=%d, dirName=*0x%x, errDialog=%d, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container);
|
||||
cellGame.error("cellHddGameCheck(version=%d, dirName=*0x%x, errDialog=%d, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container);
|
||||
|
||||
std::string dir = dirName.get_ptr();
|
||||
|
||||
@@ -78,27 +78,19 @@ s32 cellHddGameCheck(PPUThread& ppu, u32 version, vm::cptr<char> dirName, u32 er
|
||||
else
|
||||
{
|
||||
// TODO: Is cellHddGameCheck really responsible for writing the information in get->getParam ? (If not, delete this else)
|
||||
vfsFile f("/dev_hdd0/game/" + dir + "/PARAM.SFO");
|
||||
const PSFLoader psf(f);
|
||||
if (!psf)
|
||||
{
|
||||
return CELL_HDDGAME_ERROR_BROKEN;
|
||||
}
|
||||
const auto& psf = psf::load(vfsFile("/dev_hdd0/game/" + dir + "/PARAM.SFO").VRead<char>());
|
||||
|
||||
get->getParam.parentalLevel = psf.GetInteger("PARENTAL_LEVEL");
|
||||
get->getParam.attribute = psf.GetInteger("ATTRIBUTE");
|
||||
get->getParam.resolution = psf.GetInteger("RESOLUTION");
|
||||
get->getParam.soundFormat = psf.GetInteger("SOUND_FORMAT");
|
||||
std::string title = psf.GetString("TITLE");
|
||||
strcpy_trunc(get->getParam.title, title);
|
||||
std::string app_ver = psf.GetString("APP_VER");
|
||||
strcpy_trunc(get->getParam.dataVersion, app_ver);
|
||||
strcpy_trunc(get->getParam.titleId, dir);
|
||||
get->getParam.parentalLevel = psf.at("PARENTAL_LEVEL").as_integer();
|
||||
get->getParam.attribute = psf.at("ATTRIBUTE").as_integer();
|
||||
get->getParam.resolution = psf.at("RESOLUTION").as_integer();
|
||||
get->getParam.soundFormat = psf.at("SOUND_FORMAT").as_integer();
|
||||
strcpy_trunc(get->getParam.title, psf.at("TITLE").as_string());
|
||||
strcpy_trunc(get->getParam.dataVersion, psf.at("APP_VER").as_string());
|
||||
strcpy_trunc(get->getParam.titleId, psf.at("TITLE_ID").as_string());
|
||||
|
||||
for (u32 i = 0; i < CELL_HDDGAME_SYSP_LANGUAGE_NUM; i++)
|
||||
{
|
||||
title = psf.GetString(fmt::format("TITLE_%02d", i));
|
||||
strcpy_trunc(get->getParam.titleLang[i], title);
|
||||
strcpy_trunc(get->getParam.titleLang[i], psf::get_string(psf, fmt::format("TITLE_%02d", i)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,8 +131,7 @@ s32 cellHddGameExitBroken()
|
||||
|
||||
s32 cellGameDataGetSizeKB()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGame);
|
||||
return CELL_OK;
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 cellGameDataSetSystemVer()
|
||||
@@ -168,17 +159,17 @@ s32 cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
|
||||
size->sysSizeKB = 0;
|
||||
}
|
||||
|
||||
vfsFile f("/app_home/../PARAM.SFO");
|
||||
const PSFLoader psf(f);
|
||||
const auto& psf = psf::load(vfsFile("/app_home/../PARAM.SFO").VRead<char>());
|
||||
|
||||
if (!psf)
|
||||
if (psf.empty())
|
||||
{
|
||||
// According to testing (in debug mode) cellGameBootCheck doesn't return an error code, when PARAM.SFO doesn't exist.
|
||||
cellGame.error("cellGameBootCheck(): Cannot read PARAM.SFO.");
|
||||
return CELL_GAME_RET_OK;
|
||||
}
|
||||
|
||||
std::string category = psf.GetString("CATEGORY");
|
||||
if (category.substr(0, 2) == "DG")
|
||||
const std::string& category = psf.at("CATEGORY").as_string();
|
||||
if (category == "DG")
|
||||
{
|
||||
*type = CELL_GAME_GAMETYPE_DISC;
|
||||
*attributes = 0; // TODO
|
||||
@@ -189,9 +180,9 @@ s32 cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
|
||||
return CELL_GAME_ERROR_BUSY;
|
||||
}
|
||||
}
|
||||
else if (category.substr(0, 2) == "HG")
|
||||
else if (category == "HG")
|
||||
{
|
||||
std::string titleId = psf.GetString("TITLE_ID");
|
||||
const std::string& titleId = psf.at("TITLE_ID").as_string();
|
||||
*type = CELL_GAME_GAMETYPE_HDD;
|
||||
*attributes = 0; // TODO
|
||||
if (dirName) strcpy_trunc(*dirName, titleId);
|
||||
@@ -201,9 +192,9 @@ s32 cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
|
||||
return CELL_GAME_ERROR_BUSY;
|
||||
}
|
||||
}
|
||||
else if (category.substr(0, 2) == "GD")
|
||||
else if (category == "GD")
|
||||
{
|
||||
std::string titleId = psf.GetString("TITLE_ID");
|
||||
const std::string& titleId = psf.at("TITLE_ID").as_string();
|
||||
*type = CELL_GAME_GAMETYPE_DISC;
|
||||
*attributes = CELL_GAME_ATTRIBUTE_PATCH; // TODO
|
||||
if (dirName) strcpy_trunc(*dirName, titleId); // ???
|
||||
@@ -213,7 +204,7 @@ s32 cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
|
||||
return CELL_GAME_ERROR_BUSY;
|
||||
}
|
||||
}
|
||||
else if (psf)
|
||||
else
|
||||
{
|
||||
cellGame.error("cellGameBootCheck(): Unknown CATEGORY.");
|
||||
}
|
||||
@@ -235,22 +226,15 @@ s32 cellGamePatchCheck(vm::ptr<CellGameContentSize> size, vm::ptr<void> reserved
|
||||
size->sysSizeKB = 0;
|
||||
}
|
||||
|
||||
vfsFile f("/app_home/../PARAM.SFO");
|
||||
const PSFLoader psf(f);
|
||||
if (!psf)
|
||||
{
|
||||
cellGame.error("cellGamePatchCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot read PARAM.SFO)");
|
||||
return CELL_GAME_ERROR_ACCESS_ERROR;
|
||||
}
|
||||
const auto& psf = psf::load(vfsFile("/app_home/../PARAM.SFO").VRead<char>());
|
||||
|
||||
std::string category = psf.GetString("CATEGORY");
|
||||
if (category.substr(0, 2) != "GD")
|
||||
if (psf.empty() || psf.at("CATEGORY").as_string() != "GD")
|
||||
{
|
||||
cellGame.error("cellGamePatchCheck(): CELL_GAME_ERROR_NOTPATCH");
|
||||
return CELL_GAME_ERROR_NOTPATCH;
|
||||
}
|
||||
|
||||
if (!fxm::make<content_permission_t>("/dev_hdd0/game/" + psf.GetString("TITLE_ID"), false))
|
||||
if (!fxm::make<content_permission_t>("/dev_hdd0/game/" + psf.at("TITLE_ID").as_string(), false))
|
||||
{
|
||||
return CELL_GAME_ERROR_BUSY;
|
||||
}
|
||||
@@ -359,7 +343,7 @@ s32 cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm:
|
||||
|
||||
s32 cellGameDataCheckCreate2(PPUThread& ppu, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellGameDataStatCallback> funcStat, u32 container)
|
||||
{
|
||||
cellGame.warning("cellGameDataCheckCreate2(version=0x%x, dirName=*0x%x, errDialog=0x%x, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container);
|
||||
cellGame.error("cellGameDataCheckCreate2(version=0x%x, dirName=*0x%x, errDialog=0x%x, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container);
|
||||
|
||||
if (version != CELL_GAMEDATA_VERSION_CURRENT || errDialog > 1)
|
||||
{
|
||||
@@ -378,13 +362,7 @@ s32 cellGameDataCheckCreate2(PPUThread& ppu, u32 version, vm::cptr<char> dirName
|
||||
return CELL_GAMEDATA_RET_OK;
|
||||
}
|
||||
|
||||
vfsFile f("/app_home/../PARAM.SFO");
|
||||
const PSFLoader psf(f);
|
||||
if (!psf)
|
||||
{
|
||||
cellGame.error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_BROKEN (cannot read PARAM.SFO)");
|
||||
return CELL_GAMEDATA_ERROR_BROKEN;
|
||||
}
|
||||
const auto& psf = psf::load(vfsFile("/app_home/../PARAM.SFO").VRead<char>());
|
||||
|
||||
vm::var<CellGameDataCBResult> cbResult;
|
||||
vm::var<CellGameDataStatGet> cbGet;
|
||||
@@ -407,10 +385,10 @@ s32 cellGameDataCheckCreate2(PPUThread& ppu, u32 version, vm::cptr<char> dirName
|
||||
cbGet->sysSizeKB = 0;
|
||||
|
||||
cbGet->getParam.attribute = CELL_GAMEDATA_ATTR_NORMAL;
|
||||
cbGet->getParam.parentalLevel = psf.GetInteger("PARENTAL_LEVEL");
|
||||
strcpy_trunc(cbGet->getParam.dataVersion, psf.GetString("APP_VER"));
|
||||
strcpy_trunc(cbGet->getParam.titleId, psf.GetString("TITLE_ID"));
|
||||
strcpy_trunc(cbGet->getParam.title, psf.GetString("TITLE"));
|
||||
cbGet->getParam.parentalLevel = psf.at("PARENTAL_LEVEL").as_integer();
|
||||
strcpy_trunc(cbGet->getParam.dataVersion, psf.at("APP_VER").as_string());
|
||||
strcpy_trunc(cbGet->getParam.titleId, psf.at("TITLE_ID").as_string());
|
||||
strcpy_trunc(cbGet->getParam.title, psf.at("TITLE").as_string());
|
||||
// TODO: write lang titles
|
||||
|
||||
funcStat(ppu, cbResult, cbGet, cbSet);
|
||||
@@ -506,26 +484,21 @@ s32 cellGameGetParamInt(u32 id, vm::ptr<u32> value)
|
||||
{
|
||||
cellGame.warning("cellGameGetParamInt(id=%d, value=*0x%x)", id, value);
|
||||
|
||||
// TODO: Access through cellGame***Check functions
|
||||
vfsFile f("/app_home/../PARAM.SFO");
|
||||
const PSFLoader psf(f);
|
||||
const auto& psf = psf::load(vfsFile("/app_home/../PARAM.SFO").VRead<char>());
|
||||
|
||||
if (!psf)
|
||||
{
|
||||
return CELL_GAME_ERROR_FAILURE;
|
||||
}
|
||||
std::string key;
|
||||
|
||||
switch(id)
|
||||
{
|
||||
case CELL_GAME_PARAMID_PARENTAL_LEVEL: *value = psf.GetInteger("PARENTAL_LEVEL"); break;
|
||||
case CELL_GAME_PARAMID_RESOLUTION: *value = psf.GetInteger("RESOLUTION"); break;
|
||||
case CELL_GAME_PARAMID_SOUND_FORMAT: *value = psf.GetInteger("SOUND_FORMAT"); break;
|
||||
|
||||
case CELL_GAME_PARAMID_PARENTAL_LEVEL: key = "PARENTAL_LEVEL"; break;
|
||||
case CELL_GAME_PARAMID_RESOLUTION: key = "RESOLUTION"; break;
|
||||
case CELL_GAME_PARAMID_SOUND_FORMAT: key = "SOUND_FORMAT"; break;
|
||||
default:
|
||||
cellGame.error("cellGameGetParamInt(): Unimplemented parameter (%d)", id);
|
||||
return CELL_GAME_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
*value = psf.at(key).as_integer();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -533,50 +506,46 @@ s32 cellGameGetParamString(u32 id, vm::ptr<char> buf, u32 bufsize)
|
||||
{
|
||||
cellGame.warning("cellGameGetParamString(id=%d, buf=*0x%x, bufsize=%d)", id, buf, bufsize);
|
||||
|
||||
// TODO: Access through cellGame***Check functions
|
||||
vfsFile f("/app_home/../PARAM.SFO");
|
||||
const PSFLoader psf(f);
|
||||
if (!psf)
|
||||
{
|
||||
return CELL_GAME_ERROR_FAILURE;
|
||||
}
|
||||
const auto& psf = psf::load(vfsFile("/app_home/../PARAM.SFO").VRead<char>());
|
||||
|
||||
std::string data;
|
||||
std::string key;
|
||||
switch(id)
|
||||
{
|
||||
case CELL_GAME_PARAMID_TITLE: data = psf.GetString("TITLE"); break; // TODO: Is this value correct?
|
||||
case CELL_GAME_PARAMID_TITLE_DEFAULT: data = psf.GetString("TITLE"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_JAPANESE: data = psf.GetString("TITLE_00"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_ENGLISH: data = psf.GetString("TITLE_01"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_FRENCH: data = psf.GetString("TITLE_02"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_SPANISH: data = psf.GetString("TITLE_03"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_GERMAN: data = psf.GetString("TITLE_04"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_ITALIAN: data = psf.GetString("TITLE_05"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_DUTCH: data = psf.GetString("TITLE_06"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_PORTUGUESE: data = psf.GetString("TITLE_07"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_RUSSIAN: data = psf.GetString("TITLE_08"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_KOREAN: data = psf.GetString("TITLE_09"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_CHINESE_T: data = psf.GetString("TITLE_10"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_CHINESE_S: data = psf.GetString("TITLE_11"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_FINNISH: data = psf.GetString("TITLE_12"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_SWEDISH: data = psf.GetString("TITLE_13"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_DANISH: data = psf.GetString("TITLE_14"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_NORWEGIAN: data = psf.GetString("TITLE_15"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_POLISH: data = psf.GetString("TITLE_16"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_PORTUGUESE_BRAZIL: data = psf.GetString("TITLE_17"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_ENGLISH_UK: data = psf.GetString("TITLE_18"); break;
|
||||
case CELL_GAME_PARAMID_TITLE: key = "TITLE"; break; // TODO: Is this value correct?
|
||||
case CELL_GAME_PARAMID_TITLE_DEFAULT: key = "TITLE"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_JAPANESE: key = "TITLE_00"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_ENGLISH: key = "TITLE_01"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_FRENCH: key = "TITLE_02"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_SPANISH: key = "TITLE_03"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_GERMAN: key = "TITLE_04"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_ITALIAN: key = "TITLE_05"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_DUTCH: key = "TITLE_06"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_PORTUGUESE: key = "TITLE_07"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_RUSSIAN: key = "TITLE_08"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_KOREAN: key = "TITLE_09"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_CHINESE_T: key = "TITLE_10"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_CHINESE_S: key = "TITLE_11"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_FINNISH: key = "TITLE_12"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_SWEDISH: key = "TITLE_13"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_DANISH: key = "TITLE_14"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_NORWEGIAN: key = "TITLE_15"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_POLISH: key = "TITLE_16"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_PORTUGUESE_BRAZIL: key = "TITLE_17"; break;
|
||||
case CELL_GAME_PARAMID_TITLE_ENGLISH_UK: key = "TITLE_18"; break;
|
||||
|
||||
case CELL_GAME_PARAMID_TITLE_ID: data = psf.GetString("TITLE_ID"); break;
|
||||
case CELL_GAME_PARAMID_VERSION: data = psf.GetString("PS3_SYSTEM_VER"); break;
|
||||
case CELL_GAME_PARAMID_APP_VER: data = psf.GetString("APP_VER"); break;
|
||||
case CELL_GAME_PARAMID_TITLE_ID: key = "TITLE_ID"; break;
|
||||
case CELL_GAME_PARAMID_VERSION: key = "PS3_SYSTEM_VER"; break;
|
||||
case CELL_GAME_PARAMID_APP_VER: key = "APP_VER"; break;
|
||||
|
||||
default:
|
||||
cellGame.error("cellGameGetParamString(): Unimplemented parameter (%d)", id);
|
||||
return CELL_GAME_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
if (data.size() >= bufsize) data.resize(bufsize - 1);
|
||||
memcpy(buf.get_ptr(), data.c_str(), data.size() + 1);
|
||||
const std::string& value = psf.at(key).as_string().substr(0, bufsize - 1);
|
||||
|
||||
std::copy_n(value.c_str(), value.size() + 1, buf.get_ptr());
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -671,14 +640,12 @@ s32 cellGameThemeInstallFromBuffer()
|
||||
|
||||
s32 cellDiscGameGetBootDiscInfo()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGame);
|
||||
return CELL_OK;
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 cellDiscGameRegisterDiscChangeCallback()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGame);
|
||||
return CELL_OK;
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 cellDiscGameUnregisterDiscChangeCallback()
|
||||
|
||||
@@ -1189,14 +1189,12 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
|
||||
|
||||
s32 _cellGcmFunc2()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGcmSys);
|
||||
return CELL_OK;
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 _cellGcmFunc3()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGcmSys);
|
||||
return -1;
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 _cellGcmFunc4()
|
||||
@@ -1206,8 +1204,7 @@ s32 _cellGcmFunc4()
|
||||
|
||||
s32 _cellGcmFunc13()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGcmSys);
|
||||
return -1;
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 _cellGcmFunc38()
|
||||
|
||||
@@ -27,7 +27,7 @@ s32 cellMusicSetSelectionContext2()
|
||||
|
||||
s32 cellMusicSetVolume2()
|
||||
{
|
||||
return CELL_OK; //throw EXCEPTION("");
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
s32 cellMusicGetContentsId()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user