mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-02-27 21:37:37 +00:00
make gxm renderer work with new d3drm
This commit is contained in:
parent
b41e760d9d
commit
06f2179ea1
@ -67,7 +67,7 @@ if (DOWNLOAD_DEPENDENCIES)
|
||||
include(FetchContent)
|
||||
|
||||
if(VITA)
|
||||
set(SDL_PATCH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules/sdl3_vita_shaders_fix.patch")
|
||||
#set(SDL_PATCH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules/sdl3_vita_shaders_fix.patch")
|
||||
endif()
|
||||
|
||||
if(VITA_USE_OPENGLES2)
|
||||
@ -88,7 +88,10 @@ if (DOWNLOAD_DEPENDENCIES)
|
||||
set(VIDEO_VITA_PVR ON)
|
||||
get_target_property(PVR_INCLUDES GLESv2 INTERFACE_INCLUDE_DIRECTORIES)
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES ${PVR_INCLUDES})
|
||||
else()
|
||||
set(SDL_RENDER OFF)
|
||||
endif()
|
||||
|
||||
FetchContent_MakeAvailable(SDL3)
|
||||
if(VITA_USE_OPENGLES2)
|
||||
target_include_directories(SDL3-static PRIVATE ${PVR_INCLUDES})
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
#endif
|
||||
|
||||
#ifdef __vita__
|
||||
#include <SDL3/SDL_gxm.h>
|
||||
#define USE_GXM
|
||||
#endif
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ add_library(miniwin STATIC EXCLUDE_FROM_ALL
|
||||
src/ddraw/ddpalette.cpp
|
||||
src/ddraw/ddraw.cpp
|
||||
src/ddraw/ddsurface.cpp
|
||||
src/ddraw/framebuffer.cpp
|
||||
|
||||
# D3DRM
|
||||
src/d3drm/d3drm.cpp
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
shaders += main.frag.gxp main.vert.gxp
|
||||
shaders += main.frag.gxp main.vert.gxp image.frag.gxp
|
||||
shaders += clear.frag.gxp clear.vert.gxp
|
||||
shaders += blit.color.frag.gxp blit.tex.frag.gxp blit.vert.gxp
|
||||
|
||||
all: $(shaders)
|
||||
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
void main(
|
||||
float4 vPosition : POSITION,
|
||||
float2 vTexCoord : TEXCOORD0,
|
||||
|
||||
uniform float4 uColor,
|
||||
uniform int uUseTexture,
|
||||
|
||||
out float4 outColor : COLOR
|
||||
) {
|
||||
outColor = uColor;
|
||||
}
|
||||
Binary file not shown.
@ -1,12 +0,0 @@
|
||||
void main(
|
||||
float4 vPosition : POSITION,
|
||||
float2 vTexCoord : TEXCOORD0,
|
||||
|
||||
uniform float4x4 uTexMatrix,
|
||||
uniform sampler2D uTexture,
|
||||
|
||||
out float4 outColor : COLOR
|
||||
) {
|
||||
float2 samplingCoord = mul(uTexMatrix, float4(vTexCoord, 0, 1)).xy;
|
||||
outColor = tex2D(uTexture, samplingCoord);
|
||||
}
|
||||
Binary file not shown.
@ -1,12 +0,0 @@
|
||||
void main(
|
||||
float2 aPosition : POSITION,
|
||||
float2 aTexCoord : TEXCOORD0,
|
||||
|
||||
uniform float4x4 uScreenMatrix,
|
||||
|
||||
out float4 vPosition : POSITION,
|
||||
out float2 vTexCoord : TEXCOORD0
|
||||
) {
|
||||
vPosition = mul(uScreenMatrix, float4(aPosition, 0, 1));
|
||||
vTexCoord = aTexCoord;
|
||||
}
|
||||
Binary file not shown.
@ -1,5 +1,6 @@
|
||||
void main(
|
||||
uniform float4 uColor : COLOR,
|
||||
out float4 outColor : COLOR
|
||||
) {
|
||||
outColor = float4(0.0, 0.0, 0.5, 1.0);
|
||||
outColor = uColor;
|
||||
}
|
||||
|
||||
Binary file not shown.
12
miniwin/src/d3drm/backends/gxm/image.frag.cg
Normal file
12
miniwin/src/d3drm/backends/gxm/image.frag.cg
Normal file
@ -0,0 +1,12 @@
|
||||
void main(
|
||||
float4 vPosition : POSITION,
|
||||
float3 vViewPos : TEXCOORD1,
|
||||
float3 vNormal : TEXCOORD2,
|
||||
float2 vTexCoord : TEXCOORD3,
|
||||
|
||||
uniform sampler2D uTexture,
|
||||
|
||||
out float4 outColor : COLOR
|
||||
) {
|
||||
outColor = tex2D(uTexture, vTexCoord);
|
||||
}
|
||||
BIN
miniwin/src/d3drm/backends/gxm/image.frag.gxp
Normal file
BIN
miniwin/src/d3drm/backends/gxm/image.frag.gxp
Normal file
Binary file not shown.
476
miniwin/src/d3drm/backends/gxm/incbin.h
Normal file
476
miniwin/src/d3drm/backends/gxm/incbin.h
Normal file
@ -0,0 +1,476 @@
|
||||
/**
|
||||
* @file incbin.h
|
||||
* @author Dale Weiler
|
||||
* @brief Utility for including binary files
|
||||
*
|
||||
* Facilities for including binary files into the current translation unit and
|
||||
* making use from them externally in other translation units.
|
||||
*/
|
||||
#ifndef INCBIN_HDR
|
||||
#define INCBIN_HDR
|
||||
#include <limits.h>
|
||||
#if defined(__AVX512BW__) || \
|
||||
defined(__AVX512CD__) || \
|
||||
defined(__AVX512DQ__) || \
|
||||
defined(__AVX512ER__) || \
|
||||
defined(__AVX512PF__) || \
|
||||
defined(__AVX512VL__) || \
|
||||
defined(__AVX512F__)
|
||||
# define INCBIN_ALIGNMENT_INDEX 6
|
||||
#elif defined(__AVX__) || \
|
||||
defined(__AVX2__)
|
||||
# define INCBIN_ALIGNMENT_INDEX 5
|
||||
#elif defined(__SSE__) || \
|
||||
defined(__SSE2__) || \
|
||||
defined(__SSE3__) || \
|
||||
defined(__SSSE3__) || \
|
||||
defined(__SSE4_1__) || \
|
||||
defined(__SSE4_2__) || \
|
||||
defined(__neon__) || \
|
||||
defined(__ARM_NEON) || \
|
||||
defined(__ALTIVEC__)
|
||||
# define INCBIN_ALIGNMENT_INDEX 4
|
||||
#elif ULONG_MAX != 0xffffffffu
|
||||
# define INCBIN_ALIGNMENT_INDEX 3
|
||||
# else
|
||||
# define INCBIN_ALIGNMENT_INDEX 2
|
||||
#endif
|
||||
|
||||
/* Lookup table of (1 << n) where `n' is `INCBIN_ALIGNMENT_INDEX' */
|
||||
#define INCBIN_ALIGN_SHIFT_0 1
|
||||
#define INCBIN_ALIGN_SHIFT_1 2
|
||||
#define INCBIN_ALIGN_SHIFT_2 4
|
||||
#define INCBIN_ALIGN_SHIFT_3 8
|
||||
#define INCBIN_ALIGN_SHIFT_4 16
|
||||
#define INCBIN_ALIGN_SHIFT_5 32
|
||||
#define INCBIN_ALIGN_SHIFT_6 64
|
||||
|
||||
/* Actual alignment value */
|
||||
#define INCBIN_ALIGNMENT \
|
||||
INCBIN_CONCATENATE( \
|
||||
INCBIN_CONCATENATE(INCBIN_ALIGN_SHIFT, _), \
|
||||
INCBIN_ALIGNMENT_INDEX)
|
||||
|
||||
/* Stringize */
|
||||
#define INCBIN_STR(X) \
|
||||
#X
|
||||
#define INCBIN_STRINGIZE(X) \
|
||||
INCBIN_STR(X)
|
||||
/* Concatenate */
|
||||
#define INCBIN_CAT(X, Y) \
|
||||
X ## Y
|
||||
#define INCBIN_CONCATENATE(X, Y) \
|
||||
INCBIN_CAT(X, Y)
|
||||
/* Deferred macro expansion */
|
||||
#define INCBIN_EVAL(X) \
|
||||
X
|
||||
#define INCBIN_INVOKE(N, ...) \
|
||||
INCBIN_EVAL(N(__VA_ARGS__))
|
||||
/* Variable argument count for overloading by arity */
|
||||
#define INCBIN_VA_ARG_COUNTER(_1, _2, _3, N, ...) N
|
||||
#define INCBIN_VA_ARGC(...) INCBIN_VA_ARG_COUNTER(__VA_ARGS__, 3, 2, 1, 0)
|
||||
|
||||
/* Green Hills uses a different directive for including binary data */
|
||||
#if defined(__ghs__)
|
||||
# if (__ghs_asm == 2)
|
||||
# define INCBIN_MACRO ".file"
|
||||
/* Or consider the ".myrawdata" entry in the ld file */
|
||||
# else
|
||||
# define INCBIN_MACRO "\tINCBIN"
|
||||
# endif
|
||||
#else
|
||||
# define INCBIN_MACRO ".incbin"
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# define INCBIN_ALIGN \
|
||||
__attribute__((aligned(INCBIN_ALIGNMENT)))
|
||||
#else
|
||||
# define INCBIN_ALIGN __declspec(align(INCBIN_ALIGNMENT))
|
||||
#endif
|
||||
|
||||
#if defined(__arm__) || /* GNU C and RealView */ \
|
||||
defined(__arm) || /* Diab */ \
|
||||
defined(_ARM) /* ImageCraft */
|
||||
# define INCBIN_ARM
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
/* Utilize .balign where supported */
|
||||
# define INCBIN_ALIGN_HOST ".balign " INCBIN_STRINGIZE(INCBIN_ALIGNMENT) "\n"
|
||||
# define INCBIN_ALIGN_BYTE ".balign 1\n"
|
||||
#elif defined(INCBIN_ARM)
|
||||
/*
|
||||
* On arm assemblers, the alignment value is calculated as (1 << n) where `n' is
|
||||
* the shift count. This is the value passed to `.align'
|
||||
*/
|
||||
# define INCBIN_ALIGN_HOST ".align " INCBIN_STRINGIZE(INCBIN_ALIGNMENT_INDEX) "\n"
|
||||
# define INCBIN_ALIGN_BYTE ".align 0\n"
|
||||
#else
|
||||
/* We assume other inline assembler's treat `.align' as `.balign' */
|
||||
# define INCBIN_ALIGN_HOST ".align " INCBIN_STRINGIZE(INCBIN_ALIGNMENT) "\n"
|
||||
# define INCBIN_ALIGN_BYTE ".align 1\n"
|
||||
#endif
|
||||
|
||||
/* INCBIN_CONST is used by incbin.c generated files */
|
||||
#if defined(__cplusplus)
|
||||
# define INCBIN_EXTERNAL extern "C"
|
||||
# define INCBIN_CONST extern const
|
||||
#else
|
||||
# define INCBIN_EXTERNAL extern
|
||||
# define INCBIN_CONST const
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Optionally override the linker section into which size and data is
|
||||
* emitted.
|
||||
*
|
||||
* @warning If you use this facility, you might have to deal with
|
||||
* platform-specific linker output section naming on your own.
|
||||
*/
|
||||
#if !defined(INCBIN_OUTPUT_SECTION)
|
||||
# if defined(__APPLE__)
|
||||
# define INCBIN_OUTPUT_SECTION ".const_data"
|
||||
# else
|
||||
# define INCBIN_OUTPUT_SECTION ".rodata"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Optionally override the linker section into which data is emitted.
|
||||
*
|
||||
* @warning If you use this facility, you might have to deal with
|
||||
* platform-specific linker output section naming on your own.
|
||||
*/
|
||||
#if !defined(INCBIN_OUTPUT_DATA_SECTION)
|
||||
# define INCBIN_OUTPUT_DATA_SECTION INCBIN_OUTPUT_SECTION
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Optionally override the linker section into which size is emitted.
|
||||
*
|
||||
* @warning If you use this facility, you might have to deal with
|
||||
* platform-specific linker output section naming on your own.
|
||||
*
|
||||
* @note This is useful for Harvard architectures where program memory cannot
|
||||
* be directly read from the program without special instructions. With this you
|
||||
* can chose to put the size variable in RAM rather than ROM.
|
||||
*/
|
||||
#if !defined(INCBIN_OUTPUT_SIZE_SECTION)
|
||||
# define INCBIN_OUTPUT_SIZE_SECTION INCBIN_OUTPUT_SECTION
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# include <TargetConditionals.h>
|
||||
# if defined(TARGET_OS_IPHONE) && !defined(INCBIN_SILENCE_BITCODE_WARNING)
|
||||
# warning "incbin is incompatible with bitcode. Using the library will break upload to App Store if you have bitcode enabled. Add `#define INCBIN_SILENCE_BITCODE_WARNING` before including this header to silence this warning."
|
||||
# endif
|
||||
/* The directives are different for Apple branded compilers */
|
||||
# define INCBIN_SECTION INCBIN_OUTPUT_SECTION "\n"
|
||||
# define INCBIN_GLOBAL(NAME) ".globl " INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME "\n"
|
||||
# define INCBIN_INT ".long "
|
||||
# define INCBIN_MANGLE "_"
|
||||
# define INCBIN_BYTE ".byte "
|
||||
# define INCBIN_TYPE(...)
|
||||
#else
|
||||
# define INCBIN_SECTION ".section " INCBIN_OUTPUT_SECTION "\n"
|
||||
# define INCBIN_GLOBAL(NAME) ".global " INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME "\n"
|
||||
# if defined(__ghs__)
|
||||
# define INCBIN_INT ".word "
|
||||
# else
|
||||
# define INCBIN_INT ".int "
|
||||
# endif
|
||||
# if defined(__USER_LABEL_PREFIX__)
|
||||
# define INCBIN_MANGLE INCBIN_STRINGIZE(__USER_LABEL_PREFIX__)
|
||||
# else
|
||||
# define INCBIN_MANGLE ""
|
||||
# endif
|
||||
# if defined(INCBIN_ARM)
|
||||
/* On arm assemblers, `@' is used as a line comment token */
|
||||
# define INCBIN_TYPE(NAME) ".type " INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME ", %object\n"
|
||||
# elif defined(__MINGW32__) || defined(__MINGW64__) || defined(__CYGWIN__)
|
||||
/* Mingw and Cygwin don't support this directive either */
|
||||
# define INCBIN_TYPE(NAME)
|
||||
# else
|
||||
/* It's safe to use `@' on other architectures */
|
||||
# define INCBIN_TYPE(NAME) ".type " INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME ", @object\n"
|
||||
# endif
|
||||
# define INCBIN_BYTE ".byte "
|
||||
#endif
|
||||
|
||||
/* List of style types used for symbol names */
|
||||
#define INCBIN_STYLE_CAMEL 0
|
||||
#define INCBIN_STYLE_SNAKE 1
|
||||
|
||||
/**
|
||||
* @brief Specify the prefix to use for symbol names.
|
||||
*
|
||||
* @note By default this is "g".
|
||||
*
|
||||
* @code
|
||||
* #define INCBIN_PREFIX incbin
|
||||
* #include "incbin.h"
|
||||
* INCBIN(Foo, "foo.txt");
|
||||
*
|
||||
* // Now you have the following symbols instead:
|
||||
* // const unsigned char incbinFoo<data>[];
|
||||
* // const unsigned char *const incbinFoo<end>;
|
||||
* // const unsigned int incbinFoo<size>;
|
||||
* @endcode
|
||||
*/
|
||||
#if !defined(INCBIN_PREFIX)
|
||||
# define INCBIN_PREFIX g
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Specify the style used for symbol names.
|
||||
*
|
||||
* Possible options are
|
||||
* - INCBIN_STYLE_CAMEL "CamelCase"
|
||||
* - INCBIN_STYLE_SNAKE "snake_case"
|
||||
*
|
||||
* @note By default this is INCBIN_STYLE_CAMEL
|
||||
*
|
||||
* @code
|
||||
* #define INCBIN_STYLE INCBIN_STYLE_SNAKE
|
||||
* #include "incbin.h"
|
||||
* INCBIN(foo, "foo.txt");
|
||||
*
|
||||
* // Now you have the following symbols:
|
||||
* // const unsigned char <prefix>foo_data[];
|
||||
* // const unsigned char *const <prefix>foo_end;
|
||||
* // const unsigned int <prefix>foo_size;
|
||||
* @endcode
|
||||
*/
|
||||
#if !defined(INCBIN_STYLE)
|
||||
# define INCBIN_STYLE INCBIN_STYLE_CAMEL
|
||||
#endif
|
||||
|
||||
/* Style lookup tables */
|
||||
#define INCBIN_STYLE_0_DATA Data
|
||||
#define INCBIN_STYLE_0_END End
|
||||
#define INCBIN_STYLE_0_SIZE Size
|
||||
#define INCBIN_STYLE_1_DATA _data
|
||||
#define INCBIN_STYLE_1_END _end
|
||||
#define INCBIN_STYLE_1_SIZE _size
|
||||
|
||||
/* Style lookup: returning identifier */
|
||||
#define INCBIN_STYLE_IDENT(TYPE) \
|
||||
INCBIN_CONCATENATE( \
|
||||
INCBIN_STYLE_, \
|
||||
INCBIN_CONCATENATE( \
|
||||
INCBIN_EVAL(INCBIN_STYLE), \
|
||||
INCBIN_CONCATENATE(_, TYPE)))
|
||||
|
||||
/* Style lookup: returning string literal */
|
||||
#define INCBIN_STYLE_STRING(TYPE) \
|
||||
INCBIN_STRINGIZE( \
|
||||
INCBIN_STYLE_IDENT(TYPE)) \
|
||||
|
||||
/* Generate the global labels by indirectly invoking the macro with our style
|
||||
* type and concatenating the name against them. */
|
||||
#define INCBIN_GLOBAL_LABELS(NAME, TYPE) \
|
||||
INCBIN_INVOKE( \
|
||||
INCBIN_GLOBAL, \
|
||||
INCBIN_CONCATENATE( \
|
||||
NAME, \
|
||||
INCBIN_INVOKE( \
|
||||
INCBIN_STYLE_IDENT, \
|
||||
TYPE))) \
|
||||
INCBIN_INVOKE( \
|
||||
INCBIN_TYPE, \
|
||||
INCBIN_CONCATENATE( \
|
||||
NAME, \
|
||||
INCBIN_INVOKE( \
|
||||
INCBIN_STYLE_IDENT, \
|
||||
TYPE)))
|
||||
|
||||
/**
|
||||
* @brief Externally reference binary data included in another translation unit.
|
||||
*
|
||||
* Produces three external symbols that reference the binary data included in
|
||||
* another translation unit.
|
||||
*
|
||||
* The symbol names are a concatenation of `INCBIN_PREFIX' before *NAME*; with
|
||||
* "Data", as well as "End" and "Size" after. An example is provided below.
|
||||
*
|
||||
* @param TYPE Optional array type. Omitting this picks a default of `unsigned char`.
|
||||
* @param NAME The name given for the binary data
|
||||
*
|
||||
* @code
|
||||
* INCBIN_EXTERN(Foo);
|
||||
*
|
||||
* // Now you have the following symbols:
|
||||
* // extern const unsigned char <prefix>Foo<data>[];
|
||||
* // extern const unsigned char *const <prefix>Foo<end>;
|
||||
* // extern const unsigned int <prefix>Foo<size>;
|
||||
* @endcode
|
||||
*
|
||||
* You may specify a custom optional data type as well as the first argument.
|
||||
* @code
|
||||
* INCBIN_EXTERN(custom_type, Foo);
|
||||
*
|
||||
* // Now you have the following symbols:
|
||||
* // extern const custom_type <prefix>Foo<data>[];
|
||||
* // extern const custom_type *const <prefix>Foo<end>;
|
||||
* // extern const unsigned int <prefix>Foo<size>;
|
||||
* @endcode
|
||||
*/
|
||||
#define INCBIN_EXTERN(...) \
|
||||
INCBIN_CONCATENATE(INCBIN_EXTERN_, INCBIN_VA_ARGC(__VA_ARGS__))(__VA_ARGS__)
|
||||
#define INCBIN_EXTERN_1(NAME, ...) \
|
||||
INCBIN_EXTERN_2(unsigned char, NAME)
|
||||
#define INCBIN_EXTERN_2(TYPE, NAME) \
|
||||
INCBIN_EXTERNAL const INCBIN_ALIGN TYPE \
|
||||
INCBIN_CONCATENATE( \
|
||||
INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \
|
||||
INCBIN_STYLE_IDENT(DATA))[]; \
|
||||
INCBIN_EXTERNAL const INCBIN_ALIGN TYPE *const \
|
||||
INCBIN_CONCATENATE( \
|
||||
INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \
|
||||
INCBIN_STYLE_IDENT(END)); \
|
||||
INCBIN_EXTERNAL const unsigned int \
|
||||
INCBIN_CONCATENATE( \
|
||||
INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \
|
||||
INCBIN_STYLE_IDENT(SIZE))
|
||||
|
||||
/**
|
||||
* @brief Externally reference textual data included in another translation unit.
|
||||
*
|
||||
* Produces three external symbols that reference the textual data included in
|
||||
* another translation unit.
|
||||
*
|
||||
* The symbol names are a concatenation of `INCBIN_PREFIX' before *NAME*; with
|
||||
* "Data", as well as "End" and "Size" after. An example is provided below.
|
||||
*
|
||||
* @param NAME The name given for the textual data
|
||||
*
|
||||
* @code
|
||||
* INCBIN_EXTERN(Foo);
|
||||
*
|
||||
* // Now you have the following symbols:
|
||||
* // extern const char <prefix>Foo<data>[];
|
||||
* // extern const char *const <prefix>Foo<end>;
|
||||
* // extern const unsigned int <prefix>Foo<size>;
|
||||
* @endcode
|
||||
*/
|
||||
#define INCTXT_EXTERN(NAME) \
|
||||
INCBIN_EXTERN_2(char, NAME)
|
||||
|
||||
/**
|
||||
* @brief Include a binary file into the current translation unit.
|
||||
*
|
||||
* Includes a binary file into the current translation unit, producing three symbols
|
||||
* for objects that encode the data and size respectively.
|
||||
*
|
||||
* The symbol names are a concatenation of `INCBIN_PREFIX' before *NAME*; with
|
||||
* "Data", as well as "End" and "Size" after. An example is provided below.
|
||||
*
|
||||
* @param TYPE Optional array type. Omitting this picks a default of `unsigned char`.
|
||||
* @param NAME The name to associate with this binary data (as an identifier.)
|
||||
* @param FILENAME The file to include (as a string literal.)
|
||||
*
|
||||
* @code
|
||||
* INCBIN(Icon, "icon.png");
|
||||
*
|
||||
* // Now you have the following symbols:
|
||||
* // const unsigned char <prefix>Icon<data>[];
|
||||
* // const unsigned char *const <prefix>Icon<end>;
|
||||
* // const unsigned int <prefix>Icon<size>;
|
||||
* @endcode
|
||||
*
|
||||
* You may specify a custom optional data type as well as the first argument.
|
||||
* These macros are specialized by arity.
|
||||
* @code
|
||||
* INCBIN(custom_type, Icon, "icon.png");
|
||||
*
|
||||
* // Now you have the following symbols:
|
||||
* // const custom_type <prefix>Icon<data>[];
|
||||
* // const custom_type *const <prefix>Icon<end>;
|
||||
* // const unsigned int <prefix>Icon<size>;
|
||||
* @endcode
|
||||
*
|
||||
* @warning This must be used in global scope
|
||||
* @warning The identifiers may be different if INCBIN_STYLE is not default
|
||||
*
|
||||
* To externally reference the data included by this in another translation unit
|
||||
* please @see INCBIN_EXTERN.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
# define INCBIN(NAME, FILENAME) \
|
||||
INCBIN_EXTERN(NAME)
|
||||
#else
|
||||
# define INCBIN(...) \
|
||||
INCBIN_CONCATENATE(INCBIN_, INCBIN_VA_ARGC(__VA_ARGS__))(__VA_ARGS__)
|
||||
# if defined(__GNUC__)
|
||||
# define INCBIN_1(...) _Pragma("GCC error \"Single argument INCBIN not allowed\"")
|
||||
# elif defined(__clang__)
|
||||
# define INCBIN_1(...) _Pragma("clang error \"Single argument INCBIN not allowed\"")
|
||||
# else
|
||||
# define INCBIN_1(...) /* Cannot do anything here */
|
||||
# endif
|
||||
# define INCBIN_2(NAME, FILENAME) \
|
||||
INCBIN_3(unsigned char, NAME, FILENAME)
|
||||
# define INCBIN_3(TYPE, NAME, FILENAME) INCBIN_COMMON(TYPE, NAME, FILENAME, /* No terminator for binary data */)
|
||||
# define INCBIN_COMMON(TYPE, NAME, FILENAME, TERMINATOR) \
|
||||
__asm__(INCBIN_SECTION \
|
||||
INCBIN_GLOBAL_LABELS(NAME, DATA) \
|
||||
INCBIN_ALIGN_HOST \
|
||||
INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(DATA) ":\n" \
|
||||
INCBIN_MACRO " \"" FILENAME "\"\n" \
|
||||
TERMINATOR \
|
||||
INCBIN_GLOBAL_LABELS(NAME, END) \
|
||||
INCBIN_ALIGN_BYTE \
|
||||
INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(END) ":\n" \
|
||||
INCBIN_BYTE "1\n" \
|
||||
INCBIN_GLOBAL_LABELS(NAME, SIZE) \
|
||||
INCBIN_ALIGN_HOST \
|
||||
INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(SIZE) ":\n" \
|
||||
INCBIN_INT INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(END) " - " \
|
||||
INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(DATA) "\n" \
|
||||
INCBIN_ALIGN_HOST \
|
||||
".text\n" \
|
||||
); \
|
||||
INCBIN_EXTERN(TYPE, NAME)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Include a textual file into the current translation unit.
|
||||
*
|
||||
* This behaves the same as INCBIN except it produces char compatible arrays
|
||||
* and implicitly adds a null-terminator byte, thus the size of data included
|
||||
* by this is one byte larger than that of INCBIN.
|
||||
*
|
||||
* Includes a textual file into the current translation unit, producing three
|
||||
* symbols for objects that encode the data and size respectively.
|
||||
*
|
||||
* The symbol names are a concatenation of `INCBIN_PREFIX' before *NAME*; with
|
||||
* "Data", as well as "End" and "Size" after. An example is provided below.
|
||||
*
|
||||
* @param NAME The name to associate with this binary data (as an identifier.)
|
||||
* @param FILENAME The file to include (as a string literal.)
|
||||
*
|
||||
* @code
|
||||
* INCTXT(Readme, "readme.txt");
|
||||
*
|
||||
* // Now you have the following symbols:
|
||||
* // const char <prefix>Readme<data>[];
|
||||
* // const char *const <prefix>Readme<end>;
|
||||
* // const unsigned int <prefix>Readme<size>;
|
||||
* @endcode
|
||||
*
|
||||
* @warning This must be used in global scope
|
||||
* @warning The identifiers may be different if INCBIN_STYLE is not default
|
||||
*
|
||||
* To externally reference the data included by this in another translation unit
|
||||
* please @see INCBIN_EXTERN.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
# define INCTXT(NAME, FILENAME) \
|
||||
INCBIN_EXTERN(NAME)
|
||||
#else
|
||||
# define INCTXT(NAME, FILENAME) \
|
||||
INCBIN_COMMON(char, NAME, FILENAME, INCBIN_BYTE "0\n")
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -54,6 +54,7 @@ void main(
|
||||
specular += spec * lightColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outColor = uColor;
|
||||
outColor.rgb = clamp(diffuse * uColor.rgb + specular, 0.0, 1.0);
|
||||
@ -62,5 +63,4 @@ void main(
|
||||
outColor.rgb *= texel.rgb;
|
||||
outColor.rgb = clamp(outColor.rgb, 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@ -6,6 +6,8 @@
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
|
||||
|
||||
static SceUID cdramPoolUID = -1;
|
||||
static SceClibMspace cdramPool = NULL;
|
||||
|
||||
|
||||
void *patcher_host_alloc(void *user_data, unsigned int size)
|
||||
@ -126,3 +128,44 @@ void vita_mem_fragment_usse_free(SceUID uid)
|
||||
sceGxmUnmapFragmentUsseMemory(mem);
|
||||
sceKernelFreeMemBlock(uid);
|
||||
}
|
||||
|
||||
bool cdramPool_init() {
|
||||
if(cdramPool) {
|
||||
return true;
|
||||
}
|
||||
int poolsize;
|
||||
int ret;
|
||||
void* mem;
|
||||
SceKernelFreeMemorySizeInfo info;
|
||||
info.size = sizeof(SceKernelFreeMemorySizeInfo);
|
||||
sceKernelGetFreeMemorySize(&info);
|
||||
|
||||
poolsize = ALIGN(info.size_cdram, 256 * 1024);
|
||||
if (poolsize > info.size_cdram) {
|
||||
poolsize = ALIGN(info.size_cdram - 256 * 1024, 256 * 1024);
|
||||
}
|
||||
poolsize -= 16 * 1024 * 1024;
|
||||
cdramPoolUID = sceKernelAllocMemBlock("gpu_cdram_pool", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, poolsize, NULL);
|
||||
if (cdramPool < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = sceKernelGetMemBlockBase(cdramPoolUID, &mem);
|
||||
if (ret < 0) {
|
||||
return false;
|
||||
}
|
||||
cdramPool = sceClibMspaceCreate(mem, poolsize);
|
||||
|
||||
if (!cdramPool) {
|
||||
return false;
|
||||
}
|
||||
ret = sceGxmMapMemory(mem, poolsize, (SceGxmMemoryAttribFlags)(SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE));
|
||||
if (ret < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SceClibMspace cdramPool_get() {
|
||||
return cdramPool;
|
||||
}
|
||||
|
||||
@ -23,3 +23,6 @@ void *vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *u
|
||||
void vita_mem_vertex_usse_free(SceUID uid);
|
||||
void *vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
|
||||
void vita_mem_fragment_usse_free(SceUID uid);
|
||||
|
||||
bool cdramPool_init();
|
||||
SceClibMspace cdramPool_get();
|
||||
|
||||
@ -13,20 +13,20 @@
|
||||
#include <psp2/types.h>
|
||||
#include <psp2/kernel/modulemgr.h>
|
||||
|
||||
#include <SDL3/SDL_gxm.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "memory.h"
|
||||
#define INCBIN_PREFIX _inc_
|
||||
#include "incbin.h"
|
||||
|
||||
bool with_razor = false;
|
||||
|
||||
#define VITA_GXM_SCREEN_WIDTH 960
|
||||
#define VITA_GXM_SCREEN_HEIGHT 544
|
||||
#define VITA_GXM_SCREEN_STRIDE 960
|
||||
#define VITA_GXM_PENDING_SWAPS 2
|
||||
|
||||
#define VITA_GXM_SCREEN_WIDTH 960
|
||||
#define VITA_GXM_SCREEN_HEIGHT 544
|
||||
#define VITA_GXM_SCREEN_STRIDE 960
|
||||
|
||||
#define VITA_GXM_COLOR_FORMAT SCE_GXM_COLOR_FORMAT_A8B8G8R8
|
||||
#define VITA_GXM_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8
|
||||
#define VITA_GXM_COLOR_FORMAT SCE_GXM_COLOR_FORMAT_A8B8G8R8
|
||||
#define VITA_GXM_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8
|
||||
|
||||
struct SceneLightGXM {
|
||||
float color[4];
|
||||
@ -41,40 +41,17 @@ typedef struct Vertex {
|
||||
} Vertex;
|
||||
|
||||
|
||||
static bool make_fragment_program(
|
||||
GXMRendererData* data,
|
||||
const SceGxmProgram* vertexProgramGxp,
|
||||
const SceGxmBlendInfo *blendInfo,
|
||||
SceGxmFragmentProgram** fragmentProgram
|
||||
) {
|
||||
return SCE_ERR(sceGxmShaderPatcherCreateFragmentProgram,
|
||||
data->shaderPatcher,
|
||||
data->mainFragmentProgramId,
|
||||
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||
SCE_GXM_MULTISAMPLE_NONE,
|
||||
blendInfo,
|
||||
vertexProgramGxp,
|
||||
fragmentProgram
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
INCBIN("main.vert.gxp", main_vert_gxp_start);
|
||||
INCBIN("main.frag.gxp", main_frag_gxp_start);
|
||||
INCBIN("clear.vert.gxp", clear_vert_gxp_start);
|
||||
INCBIN("clear.frag.gxp", clear_frag_gxp_start);
|
||||
INCBIN("blit.vert.gxp", blit_vert_gxp_start);
|
||||
INCBIN("blit.color.frag.gxp", blit_color_frag_gxp_start);
|
||||
INCBIN("blit.tex.frag.gxp", blit_tex_frag_gxp_start);
|
||||
|
||||
const SceGxmProgram* clearVertexProgramGxp = (const SceGxmProgram*)&clear_vert_gxp_start;
|
||||
const SceGxmProgram* clearFragmentProgramGxp = (const SceGxmProgram*)&clear_frag_gxp_start;
|
||||
const SceGxmProgram* mainVertexProgramGxp = (const SceGxmProgram*)&main_vert_gxp_start;
|
||||
const SceGxmProgram* mainFragmentProgramGxp = (const SceGxmProgram*)&main_frag_gxp_start;
|
||||
const SceGxmProgram* blitVertexProgramGxp = (const SceGxmProgram*)&blit_vert_gxp_start;
|
||||
const SceGxmProgram* blitColorFragmentProgramGxp = (const SceGxmProgram*)&blit_color_frag_gxp_start;
|
||||
const SceGxmProgram* blitTexFragmentProgramGxp = (const SceGxmProgram*)&blit_tex_frag_gxp_start;
|
||||
INCBIN(main_vert_gxp, "main.vert.gxp");
|
||||
INCBIN(main_frag_gxp, "main.frag.gxp");
|
||||
INCBIN(clear_vert_gxp, "clear.vert.gxp");
|
||||
INCBIN(clear_frag_gxp, "clear.frag.gxp");
|
||||
INCBIN(image_frag_gxp, "image.frag.gxp");
|
||||
|
||||
const SceGxmProgram* mainVertexProgramGxp = (const SceGxmProgram*)_inc_main_vert_gxpData;
|
||||
const SceGxmProgram* mainFragmentProgramGxp = (const SceGxmProgram*)_inc_main_frag_gxpData;
|
||||
const SceGxmProgram* clearVertexProgramGxp = (const SceGxmProgram*)_inc_clear_vert_gxpData;
|
||||
const SceGxmProgram* clearFragmentProgramGxp = (const SceGxmProgram*)_inc_clear_frag_gxpData;
|
||||
const SceGxmProgram* imageFragmentProgramGxp = (const SceGxmProgram*)_inc_image_frag_gxpData;
|
||||
|
||||
extern "C" int sceRazorGpuCaptureSetTrigger(int frames, const char* path);
|
||||
extern "C" int sceRazorGpuCaptureEnableSalvage(const char* path);
|
||||
@ -82,15 +59,40 @@ extern "C" int sceRazorGpuCaptureSetTriggerNextFrame(const char* path);
|
||||
|
||||
static GXMRendererContext gxm_renderer_context;
|
||||
|
||||
static void display_callback(const void *callback_data) {
|
||||
const GXMDisplayData *display_data = (const GXMDisplayData *)callback_data;
|
||||
|
||||
SceDisplayFrameBuf framebuf;
|
||||
SDL_memset(&framebuf, 0x00, sizeof(SceDisplayFrameBuf));
|
||||
framebuf.size = sizeof(SceDisplayFrameBuf);
|
||||
framebuf.base = display_data->address;
|
||||
framebuf.pitch = VITA_GXM_SCREEN_STRIDE;
|
||||
framebuf.pixelformat = VITA_GXM_PIXEL_FORMAT;
|
||||
framebuf.width = VITA_GXM_SCREEN_WIDTH;
|
||||
framebuf.height = VITA_GXM_SCREEN_HEIGHT;
|
||||
sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME);
|
||||
}
|
||||
|
||||
static void load_razor() {
|
||||
int mod_id = _sceKernelLoadModule("app0:librazorcapture_es4.suprx", 0, nullptr);
|
||||
int status;
|
||||
if(!SCE_ERR(sceKernelStartModule, mod_id, 0, nullptr, 0, nullptr, &status)) {
|
||||
with_razor = true;
|
||||
}
|
||||
|
||||
if(with_razor) {
|
||||
sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx");
|
||||
}
|
||||
}
|
||||
|
||||
bool gxm_initialized = false;
|
||||
bool gxm_init() {
|
||||
if(SDL_gxm_is_init()) {
|
||||
if(gxm_initialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL_gxm_init();
|
||||
load_razor();
|
||||
|
||||
/*
|
||||
SceGxmInitializeParams initializeParams;
|
||||
SDL_memset(&initializeParams, 0, sizeof(SceGxmInitializeParams));
|
||||
initializeParams.flags = 0;
|
||||
@ -104,8 +106,9 @@ bool gxm_init() {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "gxm init failed: %d", err);
|
||||
return err;
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
gxm_initialized = true;
|
||||
|
||||
return cdramPool_init();
|
||||
}
|
||||
|
||||
static bool create_gxm_context() {
|
||||
@ -122,7 +125,7 @@ static bool create_gxm_context() {
|
||||
const unsigned int patcherVertexUsseSize = 64 * 1024;
|
||||
const unsigned int patcherFragmentUsseSize = 64 * 1024;
|
||||
|
||||
data->cdramPool = SDL_gxm_get_cdramPool();
|
||||
data->cdramPool = cdramPool_get();
|
||||
if(!data->cdramPool) {
|
||||
SDL_Log("failed to allocate cdramPool");
|
||||
return false;
|
||||
@ -253,8 +256,8 @@ bool get_gxm_context(SceGxmContext** context, SceGxmShaderPatcher** shaderPatche
|
||||
|
||||
|
||||
static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
|
||||
const unsigned int alignedWidth = ALIGN(width, SCE_GXM_TILE_SIZEX);
|
||||
const unsigned int alignedHeight = ALIGN(height, SCE_GXM_TILE_SIZEY);
|
||||
const unsigned int alignedWidth = ALIGN(VITA_GXM_SCREEN_WIDTH, SCE_GXM_TILE_SIZEX);
|
||||
const unsigned int alignedHeight = ALIGN(VITA_GXM_SCREEN_HEIGHT, SCE_GXM_TILE_SIZEY);
|
||||
|
||||
unsigned int sampleCount = alignedWidth * alignedHeight;
|
||||
unsigned int depthStrideInSamples = alignedWidth;
|
||||
@ -283,13 +286,12 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
|
||||
.alphaDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
};
|
||||
|
||||
/*
|
||||
// render target
|
||||
SceGxmRenderTargetParams renderTargetParams;
|
||||
memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams));
|
||||
renderTargetParams.flags = 0;
|
||||
renderTargetParams.width = width;
|
||||
renderTargetParams.height = height;
|
||||
renderTargetParams.width = VITA_GXM_SCREEN_WIDTH;
|
||||
renderTargetParams.height = VITA_GXM_SCREEN_HEIGHT;
|
||||
renderTargetParams.scenesPerFrame = 1;
|
||||
renderTargetParams.multisampleMode = 0;
|
||||
renderTargetParams.multisampleLocations = 0;
|
||||
@ -299,31 +301,31 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->renderBuffer = vita_mem_alloc(
|
||||
for(int i = 0; i < VITA_GXM_DISPLAY_BUFFER_COUNT; i++) {
|
||||
data->displayBuffers[i] = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
|
||||
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
|
||||
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||
&data->renderBufferUid, "display", nullptr);
|
||||
&data->displayBuffersUid[i], "display", nullptr);
|
||||
|
||||
// color surface
|
||||
if(SCE_ERR(sceGxmColorSurfaceInit,
|
||||
&data->renderSurface,
|
||||
&data->displayBuffersSurface[i],
|
||||
SCE_GXM_COLOR_FORMAT_A8B8G8R8,
|
||||
SCE_GXM_COLOR_SURFACE_LINEAR,
|
||||
SCE_GXM_COLOR_SURFACE_SCALE_NONE,
|
||||
SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,
|
||||
width, height,
|
||||
width,
|
||||
data->renderBuffer
|
||||
VITA_GXM_SCREEN_WIDTH, VITA_GXM_SCREEN_HEIGHT,
|
||||
VITA_GXM_SCREEN_STRIDE,
|
||||
data->displayBuffers[i]
|
||||
)) {
|
||||
return false;
|
||||
};
|
||||
|
||||
if(SCE_ERR(sceGxmSyncObjectCreate, &data->renderBufferSync)) {
|
||||
if(SCE_ERR(sceGxmSyncObjectCreate, &data->displayBuffersSync[i])) {
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// depth & stencil
|
||||
@ -358,15 +360,26 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// clear shader
|
||||
{
|
||||
// register shader programs
|
||||
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, clearVertexProgramGxp, &data->clearVertexProgramId)) {
|
||||
return false;
|
||||
}
|
||||
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, clearFragmentProgramGxp, &data->clearFragmentProgramId)) {
|
||||
return false;
|
||||
}
|
||||
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, mainVertexProgramGxp, &data->mainVertexProgramId)) {
|
||||
return false;
|
||||
}
|
||||
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, mainFragmentProgramGxp, &data->mainFragmentProgramId)) {
|
||||
return false;
|
||||
}
|
||||
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, imageFragmentProgramGxp, &data->imageFragmentProgramId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// clear shader
|
||||
{
|
||||
GET_SHADER_PARAM(positionAttribute, clearVertexProgramGxp, "aPosition", false);
|
||||
|
||||
SceGxmVertexAttribute vertexAttributes[1];
|
||||
@ -404,13 +417,6 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
|
||||
|
||||
// main shader
|
||||
{
|
||||
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, mainVertexProgramGxp, &data->mainVertexProgramId)) {
|
||||
return false;
|
||||
}
|
||||
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, mainFragmentProgramGxp, &data->mainFragmentProgramId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GET_SHADER_PARAM(positionAttribute, mainVertexProgramGxp, "aPosition", false);
|
||||
GET_SHADER_PARAM(normalAttribute, mainVertexProgramGxp, "aNormal", false);
|
||||
GET_SHADER_PARAM(texCoordAttribute, mainVertexProgramGxp, "aTexCoord", false);
|
||||
@ -447,18 +453,41 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
|
||||
vertexAttributes, 3,
|
||||
vertexStreams, 1,
|
||||
&data->mainVertexProgram
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
)) return false;
|
||||
}
|
||||
|
||||
if(make_fragment_program(data, mainVertexProgramGxp, &blendInfoOpaque, &data->opaqueFragmentProgram)) {
|
||||
return false;
|
||||
}
|
||||
// main opaque
|
||||
if(SCE_ERR(sceGxmShaderPatcherCreateFragmentProgram,
|
||||
data->shaderPatcher,
|
||||
data->mainFragmentProgramId,
|
||||
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||
SCE_GXM_MULTISAMPLE_NONE,
|
||||
&blendInfoOpaque,
|
||||
mainVertexProgramGxp,
|
||||
&data->opaqueFragmentProgram
|
||||
)) return false;
|
||||
|
||||
if(make_fragment_program(data, mainVertexProgramGxp, &blendInfoTransparent, &data->transparentFragmentProgram)) {
|
||||
return false;
|
||||
}
|
||||
// main transparent
|
||||
if(SCE_ERR(sceGxmShaderPatcherCreateFragmentProgram,
|
||||
data->shaderPatcher,
|
||||
data->mainFragmentProgramId,
|
||||
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||
SCE_GXM_MULTISAMPLE_NONE,
|
||||
&blendInfoTransparent,
|
||||
mainVertexProgramGxp,
|
||||
&data->transparentFragmentProgram
|
||||
)) return false;
|
||||
|
||||
// image
|
||||
if(SCE_ERR(sceGxmShaderPatcherCreateFragmentProgram,
|
||||
data->shaderPatcher,
|
||||
data->mainFragmentProgramId,
|
||||
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||
SCE_GXM_MULTISAMPLE_NONE,
|
||||
&blendInfoTransparent,
|
||||
mainVertexProgramGxp,
|
||||
&data->imageFragmentProgram
|
||||
)) return false;
|
||||
|
||||
// vertex uniforms
|
||||
data->uModelViewMatrixParam = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uModelViewMatrix");
|
||||
@ -472,6 +501,8 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
|
||||
data->uColor = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uColor"); // vec4
|
||||
data->uUseTexture = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uUseTexture"); // int
|
||||
|
||||
// clear uniforms
|
||||
data->clearShader_uColor = sceGxmProgramFindParameterByName(clearFragmentProgramGxp, "uColor"); // vec4
|
||||
|
||||
// clear mesh
|
||||
const size_t clearMeshVerticiesSize = 3 * sizeof(float)*2;
|
||||
@ -522,33 +553,10 @@ extern "C" {
|
||||
}
|
||||
*/
|
||||
|
||||
extern "C" void load_razor() {
|
||||
int mod_id = _sceKernelLoadModule("app0:librazorcapture_es4.suprx", 0, nullptr);
|
||||
int status;
|
||||
if(!SCE_ERR(sceKernelStartModule, mod_id, 0, nullptr, 0, nullptr, &status)) {
|
||||
with_razor = true;
|
||||
}
|
||||
|
||||
|
||||
if(with_razor) {
|
||||
sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx");
|
||||
}
|
||||
}
|
||||
|
||||
Direct3DRMRenderer* GXMRenderer::Create(IDirectDrawSurface* surface)
|
||||
Direct3DRMRenderer* GXMRenderer::Create(DWORD width, DWORD height)
|
||||
{
|
||||
DDSURFACEDESC DDSDesc;
|
||||
DDSDesc.dwSize = sizeof(DDSURFACEDESC);
|
||||
surface->GetSurfaceDesc(&DDSDesc);
|
||||
int width = DDSDesc.dwWidth;
|
||||
int height = DDSDesc.dwHeight;
|
||||
|
||||
FrameBufferImpl* frameBuffer = static_cast<FrameBufferImpl*>(surface);
|
||||
if(!frameBuffer) {
|
||||
SDL_Log("cant create with something that isnt a framebuffer");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SDL_Log("GXMRenderer::Create width=%d height=%d", width, height);
|
||||
|
||||
bool success = gxm_init();
|
||||
@ -561,7 +569,6 @@ Direct3DRMRenderer* GXMRenderer::Create(IDirectDrawSurface* surface)
|
||||
if(!success) {
|
||||
return nullptr;
|
||||
}
|
||||
gxm_data.frameBuffer = frameBuffer;
|
||||
|
||||
return new GXMRenderer(width, height, gxm_data);
|
||||
}
|
||||
@ -571,6 +578,7 @@ GXMRenderer::GXMRenderer(
|
||||
DWORD height,
|
||||
GXMRendererData data
|
||||
) : m_width(width), m_height(height), m_data(data) {
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
GXMRenderer::~GXMRenderer() {
|
||||
@ -578,11 +586,7 @@ GXMRenderer::~GXMRenderer() {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
sceGxmDestroyRenderTarget(this->m_data.renderTarget);
|
||||
vita_mem_free(this->m_data.renderBufferUid);
|
||||
sceGxmSyncObjectDestroy(this->m_data.renderBufferSync);
|
||||
*/
|
||||
// todo free stuff
|
||||
|
||||
vita_mem_free(this->m_data.depthBufferUid);
|
||||
this->m_data.depthBufferData = nullptr;
|
||||
@ -590,13 +594,6 @@ GXMRenderer::~GXMRenderer() {
|
||||
this->m_data.stencilBufferData = nullptr;
|
||||
}
|
||||
|
||||
void* GXMRenderer::AllocateGpu(size_t size, size_t align) {
|
||||
return sceClibMspaceMemalign(this->m_data.cdramPool, align, size);
|
||||
}
|
||||
void GXMRenderer::FreeGpu(void* ptr) {
|
||||
sceClibMspaceFree(this->m_data.cdramPool, ptr);
|
||||
}
|
||||
|
||||
void GXMRenderer::PushLights(const SceneLight* lightsArray, size_t count)
|
||||
{
|
||||
if (count > 3) {
|
||||
@ -614,7 +611,7 @@ void GXMRenderer::SetFrustumPlanes(const Plane* frustumPlanes)
|
||||
void GXMRenderer::SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back)
|
||||
{
|
||||
memcpy(&m_projection, projection, sizeof(D3DRMMATRIX4D));
|
||||
m_projection[1][1] *= -1.0f; // OpenGL is upside down
|
||||
//m_projection[1][1] *= -1.0f; // OpenGL is upside down
|
||||
}
|
||||
|
||||
struct TextureDestroyContextGLS2 {
|
||||
@ -630,7 +627,7 @@ void GXMRenderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* textu
|
||||
auto* ctx = static_cast<TextureDestroyContextGLS2*>(arg);
|
||||
auto& cache = ctx->renderer->m_textures[ctx->textureId];
|
||||
void* textureData = sceGxmTextureGetData(&cache.gxmTexture);
|
||||
ctx->renderer->FreeGpu(textureData);
|
||||
sceClibMspaceFree(ctx->renderer->m_data.cdramPool, textureData);
|
||||
delete ctx;
|
||||
},
|
||||
ctx
|
||||
@ -663,7 +660,7 @@ Uint32 GXMRenderer::GetTextureId(IDirect3DRMTexture* iTexture)
|
||||
if (!surf) {
|
||||
return NO_TEXTURE_ID;
|
||||
}
|
||||
void* textureData = this->AllocateGpu(surf->w*surf->h*4, SCE_GXM_TEXTURE_ALIGNMENT);
|
||||
void* textureData = sceClibMspaceMemalign(this->m_data.cdramPool, SCE_GXM_TEXTURE_ALIGNMENT, surf->w*surf->h*4);
|
||||
memcpy(textureData, surf->pixels, surf->w*surf->h*4);
|
||||
SDL_DestroySurface(surf);
|
||||
|
||||
@ -717,7 +714,7 @@ GXMMeshCacheEntry GXMRenderer::GXMUploadMesh(const MeshGroup& meshGroup)
|
||||
|
||||
size_t vertexBufferSize = sizeof(Vertex)*vertices.size();
|
||||
size_t indexBufferSize = sizeof(uint16_t)*indices.size();
|
||||
void* meshData = this->AllocateGpu(vertexBufferSize+indexBufferSize);
|
||||
void* meshData = sceClibMspaceMemalign(this->m_data.cdramPool, 4, vertexBufferSize+indexBufferSize);
|
||||
|
||||
Vertex* vertexBuffer = (Vertex*)meshData;
|
||||
uint16_t* indexBuffer = (uint16_t*)((uint8_t*)meshData + vertexBufferSize);
|
||||
@ -764,7 +761,7 @@ void GXMRenderer::AddMeshDestroyCallback(Uint32 id, IDirect3DRMMesh* mesh)
|
||||
auto* ctx = static_cast<GXMMeshDestroyContext*>(arg);
|
||||
auto& cache = ctx->renderer->m_meshes[ctx->id];
|
||||
cache.meshGroup = nullptr;
|
||||
ctx->renderer->FreeGpu(cache.meshData);
|
||||
sceClibMspaceFree(ctx->renderer->m_data.cdramPool, cache.meshData);
|
||||
delete ctx;
|
||||
},
|
||||
ctx
|
||||
@ -799,16 +796,6 @@ Uint32 GXMRenderer::GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup)
|
||||
return (Uint32) (m_meshes.size() - 1);
|
||||
}
|
||||
|
||||
DWORD GXMRenderer::GetWidth()
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
DWORD GXMRenderer::GetHeight()
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
|
||||
void GXMRenderer::GetDesc(D3DDEVICEDESC* halDesc, D3DDEVICEDESC* helDesc)
|
||||
{
|
||||
halDesc->dcmColorModel = D3DCOLORMODEL::RGB;
|
||||
@ -831,34 +818,32 @@ const char* GXMRenderer::GetName()
|
||||
|
||||
bool razor_triggered = false;
|
||||
|
||||
void GXMRenderer::StartScene() {
|
||||
if(sceneStarted) return;
|
||||
sceGxmBeginScene(
|
||||
this->m_data.context,
|
||||
0,
|
||||
this->m_data.renderTarget,
|
||||
nullptr,
|
||||
nullptr,
|
||||
this->m_data.displayBuffersSync[this->backBufferIndex],
|
||||
&this->m_data.displayBuffersSurface[this->backBufferIndex],
|
||||
&this->m_data.depthSurface
|
||||
);
|
||||
sceGxmSetViewport(this->m_data.context, 0, m_width, 0, m_height, 0, 0);
|
||||
this->sceneStarted = true;
|
||||
}
|
||||
|
||||
HRESULT GXMRenderer::BeginFrame()
|
||||
{
|
||||
SDL_Log("GXMRenderer::BeginFrame");
|
||||
|
||||
if(with_razor && !razor_triggered) {
|
||||
SDL_Log("trigger razor for next frame");
|
||||
sceRazorGpuCaptureSetTriggerNextFrame("ux0:/data/capture.sgx");
|
||||
razor_triggered = true;
|
||||
}
|
||||
this->transparencyEnabled = false;
|
||||
|
||||
SceGxmRenderTarget* renderTarget = this->m_data.frameBuffer->GetRenderTarget();
|
||||
GXMDisplayBuffer* backBuffer = this->m_data.frameBuffer->backBuffer();
|
||||
|
||||
sceGxmBeginScene(
|
||||
this->m_data.context,
|
||||
0,
|
||||
renderTarget,
|
||||
//this->m_data.renderTarget,
|
||||
nullptr,
|
||||
nullptr,
|
||||
backBuffer->sync,
|
||||
&backBuffer->surface,
|
||||
//this->m_data.renderBufferSync,
|
||||
//&this->m_data.renderSurface,
|
||||
&this->m_data.depthSurface
|
||||
);
|
||||
|
||||
sceGxmSetViewport(this->m_data.context, 0, m_width, 0, m_height, 0, 0);
|
||||
this->StartScene();
|
||||
|
||||
sceGxmSetFragmentUniformBuffer(this->m_data.context, 0, this->m_data.lightDataBuffer);
|
||||
|
||||
@ -874,17 +859,6 @@ HRESULT GXMRenderer::BeginFrame()
|
||||
);
|
||||
sceGxmSetFrontDepthFunc(this->m_data.context, SCE_GXM_DEPTH_FUNC_ALWAYS);
|
||||
|
||||
// clear screen
|
||||
sceGxmSetVertexProgram(this->m_data.context, this->m_data.clearVertexProgram);
|
||||
sceGxmSetFragmentProgram(this->m_data.context, this->m_data.clearFragmentProgram);
|
||||
sceGxmSetVertexStream(this->m_data.context, 0, this->m_data.clearVerticies);
|
||||
sceGxmDraw(
|
||||
this->m_data.context,
|
||||
SCE_GXM_PRIMITIVE_TRIANGLES,
|
||||
SCE_GXM_INDEX_FORMAT_U16,
|
||||
this->m_data.clearIndicies, 3
|
||||
);
|
||||
|
||||
// set light data
|
||||
int lightCount = std::min(static_cast<int>(m_lights.size()), 3);
|
||||
|
||||
@ -909,43 +883,44 @@ HRESULT GXMRenderer::BeginFrame()
|
||||
lightData[i].direction[2] = src.direction.z;
|
||||
lightData[i].direction[3] = src.directional;
|
||||
}
|
||||
|
||||
sceGxmSetVertexProgram(this->m_data.context, this->m_data.mainVertexProgram);
|
||||
sceGxmSetFragmentProgram(this->m_data.context, this->m_data.opaqueFragmentProgram);
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
void GXMRenderer::EnableTransparency()
|
||||
{
|
||||
sceGxmSetFragmentProgram(this->m_data.context, this->m_data.transparentFragmentProgram);
|
||||
void GXMRenderer::EnableTransparency() {
|
||||
this->transparencyEnabled = true;
|
||||
}
|
||||
|
||||
void TransposeD3DRMMATRIX4D(const D3DRMMATRIX4D input, D3DRMMATRIX4D output) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
output[j][i] = input[i][j];
|
||||
}
|
||||
}
|
||||
void transpose4x4(const float src[4][4], float dst[4][4]) {
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int j = 0; j < 4; ++j)
|
||||
dst[j][i] = src[i][j];
|
||||
}
|
||||
|
||||
void GXMRenderer::SubmitDraw(
|
||||
DWORD meshId,
|
||||
const D3DRMMATRIX4D& modelViewMatrix,
|
||||
const D3DRMMATRIX4D& worldMatrix,
|
||||
const D3DRMMATRIX4D& viewMatrix,
|
||||
const Matrix3x3& normalMatrix,
|
||||
const Appearance& appearance
|
||||
)
|
||||
{
|
||||
) {
|
||||
auto& mesh = m_meshes[meshId];
|
||||
|
||||
sceGxmSetVertexProgram(this->m_data.context, this->m_data.mainVertexProgram);
|
||||
if(this->transparencyEnabled) {
|
||||
sceGxmSetFragmentProgram(this->m_data.context, this->m_data.transparentFragmentProgram);
|
||||
} else {
|
||||
sceGxmSetFragmentProgram(this->m_data.context, this->m_data.opaqueFragmentProgram);
|
||||
}
|
||||
|
||||
void* vertUniforms;
|
||||
void* fragUniforms;
|
||||
sceGxmReserveVertexDefaultUniformBuffer(this->m_data.context, &vertUniforms);
|
||||
sceGxmReserveFragmentDefaultUniformBuffer(this->m_data.context, &fragUniforms);
|
||||
|
||||
SET_UNIFORM(vertUniforms, this->m_data.uModelViewMatrixParam, modelViewMatrix);
|
||||
SET_UNIFORM(vertUniforms, this->m_data.uNormalMatrixParam, normalMatrix);
|
||||
SET_UNIFORM(vertUniforms, this->m_data.uProjectionMatrixParam, m_projection);
|
||||
SET_UNIFORM(vertUniforms, this->m_data.uModelViewMatrixParam, modelViewMatrix, mainVertexProgramGxp);
|
||||
SET_UNIFORM(vertUniforms, this->m_data.uNormalMatrixParam, normalMatrix, mainVertexProgramGxp);
|
||||
SET_UNIFORM(vertUniforms, this->m_data.uProjectionMatrixParam, m_projection, mainVertexProgramGxp);
|
||||
|
||||
float color[4] = {
|
||||
appearance.color.r / 255.0f,
|
||||
@ -953,11 +928,11 @@ void GXMRenderer::SubmitDraw(
|
||||
appearance.color.b / 255.0f,
|
||||
appearance.color.a / 255.0f
|
||||
};
|
||||
SET_UNIFORM(fragUniforms, this->m_data.uColor, color);
|
||||
SET_UNIFORM(fragUniforms, this->m_data.uShininess, appearance.shininess);
|
||||
SET_UNIFORM(fragUniforms, this->m_data.uColor, color, mainFragmentProgramGxp);
|
||||
SET_UNIFORM(fragUniforms, this->m_data.uShininess, appearance.shininess, mainFragmentProgramGxp);
|
||||
|
||||
int useTexture = appearance.textureId != NO_TEXTURE_ID ? 1 : 0;
|
||||
SET_UNIFORM(fragUniforms, this->m_data.uUseTexture, useTexture);
|
||||
SET_UNIFORM(fragUniforms, this->m_data.uUseTexture, useTexture, mainFragmentProgramGxp);
|
||||
if(useTexture) {
|
||||
auto& texture = m_textures[appearance.textureId];
|
||||
sceGxmSetFragmentTexture(this->m_data.context, 0, &texture.gxmTexture);
|
||||
@ -973,21 +948,174 @@ void GXMRenderer::SubmitDraw(
|
||||
);
|
||||
}
|
||||
|
||||
HRESULT GXMRenderer::FinalizeFrame()
|
||||
{
|
||||
HRESULT GXMRenderer::FinalizeFrame() {
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
void GXMRenderer::Resize(int width, int height, const ViewportTransform& viewportTransform) {
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_viewportTransform = viewportTransform;
|
||||
}
|
||||
|
||||
void GXMRenderer::Clear(float r, float g, float b) {
|
||||
this->StartScene();
|
||||
|
||||
sceGxmSetVertexProgram(this->m_data.context, this->m_data.clearVertexProgram);
|
||||
sceGxmSetFragmentProgram(this->m_data.context, this->m_data.clearFragmentProgram);
|
||||
|
||||
void* vertUniforms;
|
||||
void* fragUniforms;
|
||||
sceGxmReserveVertexDefaultUniformBuffer(this->m_data.context, &vertUniforms);
|
||||
sceGxmReserveFragmentDefaultUniformBuffer(this->m_data.context, &fragUniforms);
|
||||
|
||||
float color[] = {r,g,b,1};
|
||||
SET_UNIFORM(fragUniforms, this->m_data.clearShader_uColor, color, clearFragmentProgramGxp);
|
||||
|
||||
sceGxmSetVertexStream(this->m_data.context, 0, this->m_data.clearVerticies);
|
||||
sceGxmDraw(
|
||||
this->m_data.context,
|
||||
SCE_GXM_PRIMITIVE_TRIANGLES,
|
||||
SCE_GXM_INDEX_FORMAT_U16,
|
||||
this->m_data.clearIndicies, 3
|
||||
);
|
||||
}
|
||||
|
||||
void GXMRenderer::Flip() {
|
||||
if(this->sceneStarted) {
|
||||
sceGxmEndScene(
|
||||
this->m_data.context,
|
||||
nullptr, nullptr
|
||||
);
|
||||
|
||||
/*
|
||||
SDL_Surface* renderedImage = SDL_CreateSurfaceFrom(
|
||||
m_width, m_height, SDL_PIXELFORMAT_ABGR8888,
|
||||
this->m_data.renderBuffer, this->m_width*4
|
||||
sceGxmPadHeartbeat(
|
||||
&this->m_data.displayBuffersSurface[this->backBufferIndex],
|
||||
this->m_data.displayBuffersSync[this->backBufferIndex]
|
||||
);
|
||||
SDL_BlitSurface(renderedImage, nullptr, DDBackBuffer, nullptr);
|
||||
SDL_DestroySurface(renderedImage);
|
||||
*/
|
||||
this->sceneStarted = false;
|
||||
}
|
||||
|
||||
return DD_OK;
|
||||
GXMDisplayData displayData;
|
||||
displayData.address = this->m_data.displayBuffers[this->backBufferIndex];
|
||||
|
||||
sceGxmDisplayQueueAddEntry(
|
||||
this->m_data.displayBuffersSync[this->frontBufferIndex],
|
||||
this->m_data.displayBuffersSync[this->backBufferIndex],
|
||||
&displayData
|
||||
);
|
||||
|
||||
this->frontBufferIndex = this->backBufferIndex;
|
||||
this->backBufferIndex = (this->backBufferIndex + 1) % VITA_GXM_DISPLAY_BUFFER_COUNT;
|
||||
}
|
||||
|
||||
void CreateOrthoMatrix(float left, float right, float bottom, float top, D3DRMMATRIX4D& outMatrix)
|
||||
{
|
||||
float near = -1.0f;
|
||||
float far = 1.0f;
|
||||
float rl = right - left;
|
||||
float tb = top - bottom;
|
||||
float fn = far - near;
|
||||
|
||||
outMatrix[0][0] = 2.0f / rl;
|
||||
outMatrix[0][1] = 0.0f;
|
||||
outMatrix[0][2] = 0.0f;
|
||||
outMatrix[0][3] = 0.0f;
|
||||
|
||||
outMatrix[1][0] = 0.0f;
|
||||
outMatrix[1][1] = 2.0f / tb;
|
||||
outMatrix[1][2] = 0.0f;
|
||||
outMatrix[1][3] = 0.0f;
|
||||
|
||||
outMatrix[2][0] = 0.0f;
|
||||
outMatrix[2][1] = 0.0f;
|
||||
outMatrix[2][2] = -2.0f / fn;
|
||||
outMatrix[2][3] = 0.0f;
|
||||
|
||||
outMatrix[3][0] = -(right + left) / rl;
|
||||
outMatrix[3][1] = -(top + bottom) / tb;
|
||||
outMatrix[3][2] = -(far + near) / fn;
|
||||
outMatrix[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) {
|
||||
this->StartScene();
|
||||
|
||||
sceGxmSetVertexProgram(this->m_data.context, this->m_data.mainVertexProgram);
|
||||
sceGxmSetFragmentProgram(this->m_data.context, this->m_data.imageFragmentProgram);
|
||||
|
||||
void* vertUniforms;
|
||||
void* fragUniforms;
|
||||
sceGxmReserveVertexDefaultUniformBuffer(this->m_data.context, &vertUniforms);
|
||||
sceGxmReserveFragmentDefaultUniformBuffer(this->m_data.context, &fragUniforms);
|
||||
|
||||
float left = -m_viewportTransform.offsetX / m_viewportTransform.scale;
|
||||
float right = (m_width - m_viewportTransform.offsetX) / m_viewportTransform.scale;
|
||||
float top = -m_viewportTransform.offsetY / m_viewportTransform.scale;
|
||||
float bottom = (m_height - m_viewportTransform.offsetY) / m_viewportTransform.scale;
|
||||
|
||||
D3DRMMATRIX4D projection;
|
||||
CreateOrthoMatrix(left, right, bottom, top, projection);
|
||||
|
||||
D3DRMMATRIX4D identity = {{1.f, 0.f, 0.f, 0.f}, {0.f, 1.f, 0.f, 0.f}, {0.f, 0.f, 1.f, 0.f}, {0.f, 0.f, 0.f, 1.f}};
|
||||
|
||||
SET_UNIFORM(vertUniforms, this->m_data.uModelViewMatrixParam, identity, mainVertexProgramGxp);
|
||||
SET_UNIFORM(vertUniforms, this->m_data.uNormalMatrixParam, identity, mainVertexProgramGxp);
|
||||
SET_UNIFORM(vertUniforms, this->m_data.uProjectionMatrixParam, m_projection, mainVertexProgramGxp);
|
||||
|
||||
const GXMTextureCacheEntry& texture = m_textures[textureId];
|
||||
sceGxmSetFragmentTexture(this->m_data.context, 0, &texture.gxmTexture);
|
||||
|
||||
float texW = sceGxmTextureGetWidth(&texture.gxmTexture);
|
||||
float texH = sceGxmTextureGetHeight(&texture.gxmTexture);
|
||||
|
||||
float u1 = srcRect.x / texW;
|
||||
float v1 = srcRect.y / texH;
|
||||
float u2 = (srcRect.x + srcRect.w) / texW;
|
||||
float v2 = (srcRect.y + srcRect.h) / texH;
|
||||
|
||||
float x1 = static_cast<float>(dstRect.x);
|
||||
float y1 = static_cast<float>(dstRect.y);
|
||||
float x2 = x1 + dstRect.w;
|
||||
float y2 = y1 + dstRect.h;
|
||||
|
||||
void* meshBuffer = sceClibMspaceMalloc(this->m_data.cdramPool, 4*sizeof(Vertex) + 4*sizeof(uint16_t));
|
||||
Vertex* gpuVertices = (Vertex*)meshBuffer;
|
||||
uint16_t* gpuIndices = (uint16_t*)(((uint8_t*)meshBuffer) + 4*sizeof(Vertex));
|
||||
|
||||
gpuVertices[0] = Vertex{ .position = {x1, y1, 0}, .normal = {0,0,0}, .texCoord = {u1, v1}};
|
||||
gpuVertices[1] = Vertex{ .position = {x2, y1, 0}, .normal = {0,0,0}, .texCoord = {u2, v1}};
|
||||
gpuVertices[2] = Vertex{ .position = {x1, y2, 0}, .normal = {0,0,0}, .texCoord = {u1, v2}};
|
||||
gpuVertices[3] = Vertex{ .position = {x2, y2, 0}, .normal = {0,0,0}, .texCoord = {u2, v2}};
|
||||
|
||||
gpuIndices[0] = 0;
|
||||
gpuIndices[1] = 1;
|
||||
gpuIndices[2] = 2;
|
||||
gpuIndices[3] = 3;
|
||||
|
||||
sceGxmSetVertexStream(this->m_data.context, 0, gpuVertices);
|
||||
sceGxmDraw(
|
||||
this->m_data.context,
|
||||
SCE_GXM_PRIMITIVE_TRIANGLE_STRIP,
|
||||
SCE_GXM_INDEX_FORMAT_U16,
|
||||
gpuIndices, 4
|
||||
);
|
||||
|
||||
sceClibMspaceFree(this->m_data.cdramPool, meshBuffer);
|
||||
}
|
||||
|
||||
void GXMRenderer::Download(SDL_Surface* target) {
|
||||
SDL_Surface* src = SDL_CreateSurfaceFrom(
|
||||
this->m_width, this->m_height,
|
||||
SDL_PIXELFORMAT_RGBA32,
|
||||
this->m_data.displayBuffers[this->backBufferIndex], VITA_GXM_SCREEN_STRIDE
|
||||
);
|
||||
|
||||
SDL_Rect srcRect = {
|
||||
static_cast<int>(m_viewportTransform.offsetX),
|
||||
static_cast<int>(m_viewportTransform.offsetY),
|
||||
static_cast<int>(target->w * m_viewportTransform.scale),
|
||||
static_cast<int>(target->h * m_viewportTransform.scale),
|
||||
};
|
||||
|
||||
SDL_BlitSurfaceScaled(src, &srcRect, target, nullptr, SDL_SCALEMODE_NEAREST);
|
||||
}
|
||||
|
||||
@ -15,19 +15,14 @@
|
||||
|
||||
#define ALIGN(x, a) (((x) + ((a)-1)) & ~((a)-1))
|
||||
|
||||
#define INCBIN(filename, symbol) \
|
||||
__asm__( \
|
||||
".balign 16 \n" \
|
||||
#symbol ":" \
|
||||
".incbin \"" filename "\"" \
|
||||
); \
|
||||
extern const void* symbol
|
||||
|
||||
#define SET_UNIFORM(buffer, param, value) \
|
||||
#define SET_UNIFORM(buffer, param, value, program) \
|
||||
do { \
|
||||
size_t __offset = sceGxmProgramParameterGetResourceIndex(param); \
|
||||
void* __dst = (uint8_t*)(buffer) + (__offset * sizeof(uint32_t)); \
|
||||
memcpy(__dst, reinterpret_cast<const void*>(&(value)), sizeof(value)); \
|
||||
/*SDL_Log("set uniform param=%s offset=%d size=%d buffer_size=%d", \
|
||||
sceGxmProgramParameterGetName(param), __offset*4, sizeof(value), sceGxmProgramGetDefaultUniformBufferSize(program));*/ \
|
||||
} while (0)
|
||||
|
||||
#define GET_SHADER_PARAM(var, gxp, name, ret) \
|
||||
@ -36,10 +31,3 @@
|
||||
SDL_Log("Failed to find param %s", name); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
|
||||
extern const SceGxmProgram* blitVertexProgramGxp;
|
||||
extern const SceGxmProgram* blitColorFragmentProgramGxp;
|
||||
extern const SceGxmProgram* blitTexFragmentProgramGxp;
|
||||
|
||||
bool get_gxm_context(SceGxmContext** context, SceGxmShaderPatcher** shaderPatcher, SceClibMspace* cdramPool);
|
||||
|
||||
@ -173,7 +173,7 @@ HRESULT Direct3DRMImpl::CreateDeviceFromSurface(
|
||||
#endif
|
||||
#ifdef __vita__
|
||||
else if (SDL_memcmp(&guid, &GXM_GUID, sizeof(GUID)) == 0) {
|
||||
DDRenderer = GXMRenderer::Create(surface);
|
||||
DDRenderer = GXMRenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
|
||||
@ -227,7 +227,7 @@ HRESULT DirectDrawImpl::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx)
|
||||
Direct3DRMSDL3GPU_EnumDevice(cb, ctx);
|
||||
#endif
|
||||
#ifdef USE_OPENGLES2
|
||||
//OpenGLES2Renderer_EnumDevice(cb, ctx);
|
||||
OpenGLES2Renderer_EnumDevice(cb, ctx);
|
||||
#endif
|
||||
#ifdef USE_OPENGL1
|
||||
OpenGL1Renderer_EnumDevice(cb, ctx);
|
||||
@ -236,9 +236,9 @@ HRESULT DirectDrawImpl::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx)
|
||||
DirectX9Renderer_EnumDevice(cb, ctx);
|
||||
#endif
|
||||
#ifdef __vita__
|
||||
//GXMRenderer_EnumDevice(cb, ctx);
|
||||
GXMRenderer_EnumDevice(cb, ctx);
|
||||
#endif
|
||||
Direct3DRMSoftware_EnumDevice(cb, ctx);
|
||||
//Direct3DRMSoftware_EnumDevice(cb, ctx);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@ -365,7 +365,7 @@ HRESULT DirectDrawImpl::CreateDevice(
|
||||
#endif
|
||||
#ifdef __vita__
|
||||
else if (SDL_memcmp(&guid, &GXM_GUID, sizeof(GUID)) == 0) {
|
||||
DDRenderer = GXMRenderer::Create(pBackBuffer);
|
||||
DDRenderer = GXMRenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight);
|
||||
}
|
||||
#endif
|
||||
else if (SDL_memcmp(&guid, &SOFTWARE_GUID, sizeof(GUID)) == 0) {
|
||||
|
||||
@ -32,6 +32,10 @@ struct GXMMeshCacheEntry {
|
||||
uint16_t indexCount;
|
||||
};
|
||||
|
||||
typedef struct GXMDisplayData {
|
||||
void* address;
|
||||
} GXMDisplayData;
|
||||
|
||||
typedef struct GXMRendererContext {
|
||||
// context
|
||||
SceUID vdmRingBufferUid;
|
||||
@ -70,14 +74,11 @@ typedef struct GXMRendererData {
|
||||
SceGxmShaderPatcher* shaderPatcher;
|
||||
SceClibMspace cdramPool;
|
||||
|
||||
// color buffer
|
||||
/*
|
||||
SceGxmRenderTarget* renderTarget;
|
||||
SceUID renderBufferUid;
|
||||
void* renderBuffer;
|
||||
SceGxmColorSurface renderSurface;
|
||||
SceGxmSyncObject* renderBufferSync;
|
||||
*/
|
||||
void* displayBuffers[VITA_GXM_DISPLAY_BUFFER_COUNT];
|
||||
SceUID displayBuffersUid[VITA_GXM_DISPLAY_BUFFER_COUNT];
|
||||
SceGxmColorSurface displayBuffersSurface[VITA_GXM_DISPLAY_BUFFER_COUNT];
|
||||
SceGxmSyncObject* displayBuffersSync[VITA_GXM_DISPLAY_BUFFER_COUNT];
|
||||
|
||||
// depth buffer
|
||||
SceUID depthBufferUid;
|
||||
@ -95,9 +96,11 @@ typedef struct GXMRendererData {
|
||||
// main shader
|
||||
SceGxmShaderPatcherId mainVertexProgramId;
|
||||
SceGxmShaderPatcherId mainFragmentProgramId;
|
||||
SceGxmShaderPatcherId imageFragmentProgramId;
|
||||
SceGxmVertexProgram* mainVertexProgram;
|
||||
SceGxmFragmentProgram* opaqueFragmentProgram;
|
||||
SceGxmFragmentProgram* transparentFragmentProgram;
|
||||
SceGxmFragmentProgram* opaqueFragmentProgram; // 3d with no transparency
|
||||
SceGxmFragmentProgram* transparentFragmentProgram; // 3d with transparency
|
||||
SceGxmFragmentProgram* imageFragmentProgram; // 2d images, no lighting
|
||||
|
||||
// main shader vertex uniforms
|
||||
const SceGxmProgramParameter* uModelViewMatrixParam;
|
||||
@ -111,6 +114,8 @@ typedef struct GXMRendererData {
|
||||
const SceGxmProgramParameter* uColor;
|
||||
const SceGxmProgramParameter* uUseTexture;
|
||||
|
||||
const SceGxmProgramParameter* clearShader_uColor;
|
||||
|
||||
// clear mesh
|
||||
void* clearMeshBuffer;
|
||||
float* clearVerticies;
|
||||
@ -118,13 +123,11 @@ typedef struct GXMRendererData {
|
||||
|
||||
// scene light data
|
||||
void* lightDataBuffer;
|
||||
|
||||
FrameBufferImpl* frameBuffer;
|
||||
} GXMRendererData;
|
||||
|
||||
class GXMRenderer : public Direct3DRMRenderer {
|
||||
public:
|
||||
static Direct3DRMRenderer* Create(IDirectDrawSurface* surface);
|
||||
static Direct3DRMRenderer* Create(DWORD width, DWORD height);
|
||||
GXMRenderer(
|
||||
DWORD width,
|
||||
DWORD height,
|
||||
@ -138,8 +141,6 @@ class GXMRenderer : public Direct3DRMRenderer {
|
||||
void SetFrustumPlanes(const Plane* frustumPlanes) override;
|
||||
Uint32 GetTextureId(IDirect3DRMTexture* texture) override;
|
||||
Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override;
|
||||
DWORD GetWidth() override;
|
||||
DWORD GetHeight() override;
|
||||
void GetDesc(D3DDEVICEDESC* halDesc, D3DDEVICEDESC* helDesc) override;
|
||||
const char* GetName() override;
|
||||
HRESULT BeginFrame() override;
|
||||
@ -147,26 +148,38 @@ class GXMRenderer : public Direct3DRMRenderer {
|
||||
void SubmitDraw(
|
||||
DWORD meshId,
|
||||
const D3DRMMATRIX4D& modelViewMatrix,
|
||||
const D3DRMMATRIX4D& worldMatrix,
|
||||
const D3DRMMATRIX4D& viewMatrix,
|
||||
const Matrix3x3& normalMatrix,
|
||||
const Appearance& appearance
|
||||
) override;
|
||||
HRESULT FinalizeFrame() override;
|
||||
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
||||
void Clear(float r, float g, float b) override;
|
||||
void Flip() override;
|
||||
void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override;
|
||||
void Download(SDL_Surface* target) override;
|
||||
|
||||
private:
|
||||
void AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture);
|
||||
void AddMeshDestroyCallback(Uint32 id, IDirect3DRMMesh* mesh);
|
||||
|
||||
void* AllocateGpu(size_t size, size_t align = 4);
|
||||
void FreeGpu(void* ptr);
|
||||
|
||||
GXMMeshCacheEntry GXMUploadMesh(const MeshGroup& meshGroup);
|
||||
|
||||
void StartScene();
|
||||
|
||||
std::vector<GXMTextureCacheEntry> m_textures;
|
||||
std::vector<GXMMeshCacheEntry> m_meshes;
|
||||
D3DRMMATRIX4D m_projection;
|
||||
DWORD m_width, m_height;
|
||||
std::vector<SceneLight> m_lights;
|
||||
|
||||
bool transparencyEnabled = false;
|
||||
bool sceneStarted = false;
|
||||
|
||||
int backBufferIndex = 0;
|
||||
int frontBufferIndex = 1;
|
||||
|
||||
GXMRendererData m_data;
|
||||
bool m_initialized = false;
|
||||
};
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __vita__
|
||||
#include "framebuffer_impl_vita.h"
|
||||
#else
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <ddsurface_impl.h>
|
||||
#include <miniwin/ddraw.h>
|
||||
@ -46,4 +42,3 @@ struct FrameBufferImpl : public IDirectDrawSurface3 {
|
||||
DirectDrawSurfaceImpl* m_transferBuffer;
|
||||
IDirectDrawPalette* m_palette = nullptr;
|
||||
};
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user