mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-02-28 05:47:38 +00:00
improve fragment shader performance
This commit is contained in:
parent
fca27bf78d
commit
450ce40b01
@ -6,7 +6,7 @@
|
|||||||
void* patcher_host_alloc(void* user_data, unsigned int size);
|
void* patcher_host_alloc(void* user_data, unsigned int size);
|
||||||
void patcher_host_free(void* user_data, void* mem);
|
void patcher_host_free(void* user_data, void* mem);
|
||||||
|
|
||||||
void* vita_mem_alloc(unsigned int type, size_t size, size_t alignment, int attribs, SceUID* uid);
|
void* vita_mem_alloc(unsigned int type, size_t size, size_t alignment, int attribs, SceUID* uid, const char* name);
|
||||||
void vita_mem_free(SceUID uid);
|
void vita_mem_free(SceUID uid);
|
||||||
|
|
||||||
void* vita_mem_vertex_usse_alloc(unsigned int size, SceUID* uid, unsigned int* usse_offset);
|
void* vita_mem_vertex_usse_alloc(unsigned int size, SceUID* uid, unsigned int* usse_offset);
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
#define INCBIN_PREFIX _inc_
|
#define INCBIN_PREFIX _inc_
|
||||||
#include "incbin.h"
|
#include "incbin.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
bool with_razor = false;
|
bool with_razor = false;
|
||||||
bool with_razor_hud = false;
|
bool with_razor_hud = false;
|
||||||
bool gxm_initialized = false;
|
bool gxm_initialized = false;
|
||||||
@ -28,13 +30,17 @@ bool gxm_initialized = false;
|
|||||||
#define VITA_GXM_COLOR_FORMAT SCE_GXM_COLOR_FORMAT_A8B8G8R8
|
#define VITA_GXM_COLOR_FORMAT SCE_GXM_COLOR_FORMAT_A8B8G8R8
|
||||||
#define VITA_GXM_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8
|
#define VITA_GXM_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8
|
||||||
|
|
||||||
|
#define SCE_GXM_PRECOMPUTED_ALIGNMENT 16
|
||||||
|
|
||||||
INCBIN(main_vert_gxp, "shaders/main.vert.gxp");
|
INCBIN(main_vert_gxp, "shaders/main.vert.gxp");
|
||||||
INCBIN(main_frag_gxp, "shaders/main.frag.gxp");
|
INCBIN(main_color_frag_gxp, "shaders/main.color.frag.gxp");
|
||||||
|
INCBIN(main_texture_frag_gxp, "shaders/main.texture.frag.gxp");
|
||||||
INCBIN(color_frag_gxp, "shaders/color.frag.gxp");
|
INCBIN(color_frag_gxp, "shaders/color.frag.gxp");
|
||||||
INCBIN(image_frag_gxp, "shaders/image.frag.gxp");
|
INCBIN(image_frag_gxp, "shaders/image.frag.gxp");
|
||||||
|
|
||||||
const SceGxmProgram* mainVertexProgramGxp = (const SceGxmProgram*) _inc_main_vert_gxpData;
|
const SceGxmProgram* mainVertexProgramGxp = (const SceGxmProgram*) _inc_main_vert_gxpData;
|
||||||
const SceGxmProgram* mainFragmentProgramGxp = (const SceGxmProgram*) _inc_main_frag_gxpData;
|
const SceGxmProgram* mainColorFragmentProgramGxp = (const SceGxmProgram*) _inc_main_color_frag_gxpData;
|
||||||
|
const SceGxmProgram* mainTextureFragmentProgramGxp = (const SceGxmProgram*) _inc_main_texture_frag_gxpData;
|
||||||
const SceGxmProgram* colorFragmentProgramGxp = (const SceGxmProgram*) _inc_color_frag_gxpData;
|
const SceGxmProgram* colorFragmentProgramGxp = (const SceGxmProgram*) _inc_color_frag_gxpData;
|
||||||
const SceGxmProgram* imageFragmentProgramGxp = (const SceGxmProgram*) _inc_image_frag_gxpData;
|
const SceGxmProgram* imageFragmentProgramGxp = (const SceGxmProgram*) _inc_image_frag_gxpData;
|
||||||
|
|
||||||
@ -129,7 +135,7 @@ static void load_razor()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (with_razor) {
|
if (with_razor) {
|
||||||
sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx");
|
//sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (with_razor_hud) {
|
if (with_razor_hud) {
|
||||||
@ -183,7 +189,8 @@ static bool create_gxm_context()
|
|||||||
SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE,
|
SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE,
|
||||||
4,
|
4,
|
||||||
SCE_GXM_MEMORY_ATTRIB_READ,
|
SCE_GXM_MEMORY_ATTRIB_READ,
|
||||||
&data->vdmRingBufferUid
|
&data->vdmRingBufferUid,
|
||||||
|
"vdmRingBuffer"
|
||||||
);
|
);
|
||||||
|
|
||||||
data->vertexRingBuffer = vita_mem_alloc(
|
data->vertexRingBuffer = vita_mem_alloc(
|
||||||
@ -191,7 +198,8 @@ static bool create_gxm_context()
|
|||||||
SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE,
|
SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE,
|
||||||
4,
|
4,
|
||||||
SCE_GXM_MEMORY_ATTRIB_READ,
|
SCE_GXM_MEMORY_ATTRIB_READ,
|
||||||
&data->vertexRingBufferUid
|
&data->vertexRingBufferUid,
|
||||||
|
"vertexRingBuffer"
|
||||||
);
|
);
|
||||||
|
|
||||||
data->fragmentRingBuffer = vita_mem_alloc(
|
data->fragmentRingBuffer = vita_mem_alloc(
|
||||||
@ -199,7 +207,8 @@ static bool create_gxm_context()
|
|||||||
SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE,
|
SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE,
|
||||||
4,
|
4,
|
||||||
SCE_GXM_MEMORY_ATTRIB_READ,
|
SCE_GXM_MEMORY_ATTRIB_READ,
|
||||||
&data->fragmentRingBufferUid
|
&data->fragmentRingBufferUid,
|
||||||
|
"fragmentRingBuffer"
|
||||||
);
|
);
|
||||||
|
|
||||||
data->fragmentUsseRingBuffer = vita_mem_fragment_usse_alloc(
|
data->fragmentUsseRingBuffer = vita_mem_fragment_usse_alloc(
|
||||||
@ -234,7 +243,8 @@ static bool create_gxm_context()
|
|||||||
patcherBufferSize,
|
patcherBufferSize,
|
||||||
4,
|
4,
|
||||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||||
&data->patcherBufferUid
|
&data->patcherBufferUid,
|
||||||
|
"patcherBuffer"
|
||||||
);
|
);
|
||||||
|
|
||||||
data->patcherVertexUsse =
|
data->patcherVertexUsse =
|
||||||
@ -373,7 +383,8 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
|
|||||||
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
|
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
|
||||||
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
|
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
|
||||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||||
&this->displayBuffersUid[i]
|
&this->displayBuffersUid[i],
|
||||||
|
"displayBuffers"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (SCE_ERR(
|
if (SCE_ERR(
|
||||||
@ -402,7 +413,8 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
|
|||||||
4 * sampleCount,
|
4 * sampleCount,
|
||||||
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
||||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||||
&this->depthBufferUid
|
&this->depthBufferUid,
|
||||||
|
"depthBufferData"
|
||||||
);
|
);
|
||||||
|
|
||||||
this->stencilBufferData = vita_mem_alloc(
|
this->stencilBufferData = vita_mem_alloc(
|
||||||
@ -410,7 +422,8 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
|
|||||||
4 * sampleCount,
|
4 * sampleCount,
|
||||||
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
||||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||||
&this->stencilBufferUid
|
&this->stencilBufferUid,
|
||||||
|
"stencilBufferData"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (SCE_ERR(
|
if (SCE_ERR(
|
||||||
@ -445,8 +458,16 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
|
|||||||
if (SCE_ERR(
|
if (SCE_ERR(
|
||||||
sceGxmShaderPatcherRegisterProgram,
|
sceGxmShaderPatcherRegisterProgram,
|
||||||
this->shaderPatcher,
|
this->shaderPatcher,
|
||||||
mainFragmentProgramGxp,
|
mainColorFragmentProgramGxp,
|
||||||
&this->mainFragmentProgramId
|
&this->mainColorFragmentProgramId
|
||||||
|
)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (SCE_ERR(
|
||||||
|
sceGxmShaderPatcherRegisterProgram,
|
||||||
|
this->shaderPatcher,
|
||||||
|
mainTextureFragmentProgramGxp,
|
||||||
|
&this->mainTextureFragmentProgramId
|
||||||
)) {
|
)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -505,30 +526,58 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// main opaque
|
// main color opaque
|
||||||
if (SCE_ERR(
|
if (SCE_ERR(
|
||||||
sceGxmShaderPatcherCreateFragmentProgram,
|
sceGxmShaderPatcherCreateFragmentProgram,
|
||||||
this->shaderPatcher,
|
this->shaderPatcher,
|
||||||
this->mainFragmentProgramId,
|
this->mainColorFragmentProgramId,
|
||||||
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||||
SCE_GXM_MULTISAMPLE_NONE,
|
SCE_GXM_MULTISAMPLE_NONE,
|
||||||
&blendInfoOpaque,
|
&blendInfoOpaque,
|
||||||
mainVertexProgramGxp,
|
mainVertexProgramGxp,
|
||||||
&this->opaqueFragmentProgram
|
&this->opaqueColorFragmentProgram
|
||||||
)) {
|
)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// main transparent
|
// main color blended
|
||||||
if (SCE_ERR(
|
if (SCE_ERR(
|
||||||
sceGxmShaderPatcherCreateFragmentProgram,
|
sceGxmShaderPatcherCreateFragmentProgram,
|
||||||
this->shaderPatcher,
|
this->shaderPatcher,
|
||||||
this->mainFragmentProgramId,
|
this->mainColorFragmentProgramId,
|
||||||
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||||
SCE_GXM_MULTISAMPLE_NONE,
|
SCE_GXM_MULTISAMPLE_NONE,
|
||||||
&blendInfoTransparent,
|
&blendInfoTransparent,
|
||||||
mainVertexProgramGxp,
|
mainVertexProgramGxp,
|
||||||
&this->transparentFragmentProgram
|
&this->blendedColorFragmentProgram
|
||||||
|
)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// main texture opaque
|
||||||
|
if (SCE_ERR(
|
||||||
|
sceGxmShaderPatcherCreateFragmentProgram,
|
||||||
|
this->shaderPatcher,
|
||||||
|
this->mainTextureFragmentProgramId,
|
||||||
|
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||||
|
SCE_GXM_MULTISAMPLE_NONE,
|
||||||
|
&blendInfoOpaque,
|
||||||
|
mainVertexProgramGxp,
|
||||||
|
&this->opaqueTextureFragmentProgram
|
||||||
|
)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// main texture transparent
|
||||||
|
if (SCE_ERR(
|
||||||
|
sceGxmShaderPatcherCreateFragmentProgram,
|
||||||
|
this->shaderPatcher,
|
||||||
|
this->mainTextureFragmentProgramId,
|
||||||
|
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||||
|
SCE_GXM_MULTISAMPLE_NONE,
|
||||||
|
&blendInfoTransparent,
|
||||||
|
mainVertexProgramGxp,
|
||||||
|
&this->blendedTextureFragmentProgram
|
||||||
)) {
|
)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -567,11 +616,14 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
|
|||||||
this->uProjectionMatrix = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uProjectionMatrix");
|
this->uProjectionMatrix = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uProjectionMatrix");
|
||||||
|
|
||||||
// fragment uniforms
|
// fragment uniforms
|
||||||
this->uLights = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uLights"); // SceneLight[3]
|
this->color_uLights = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uLights"); // SceneLight[3]
|
||||||
this->uLightCount = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uLightCount"); // int
|
this->color_uAmbientLight = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uAmbientLight"); // vec3
|
||||||
this->uShininess = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uShininess"); // float
|
this->color_uShininess = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uShininess"); // float
|
||||||
this->uColor = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uColor"); // vec4
|
this->color_uColor = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uColor"); // vec4
|
||||||
this->uUseTexture = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uUseTexture"); // int
|
this->texture_uLights = sceGxmProgramFindParameterByName(mainTextureFragmentProgramGxp, "uLights"); // SceneLight[3]
|
||||||
|
this->texture_uAmbientLight = sceGxmProgramFindParameterByName(mainTextureFragmentProgramGxp, "uAmbientLight"); // vec3
|
||||||
|
this->texture_uShininess = sceGxmProgramFindParameterByName(mainTextureFragmentProgramGxp, "uShininess"); // float
|
||||||
|
this->texture_uColor = sceGxmProgramFindParameterByName(mainTextureFragmentProgramGxp, "uColor"); // vec4
|
||||||
|
|
||||||
// clear uniforms
|
// clear uniforms
|
||||||
this->colorShader_uColor = sceGxmProgramFindParameterByName(colorFragmentProgramGxp, "uColor"); // vec4
|
this->colorShader_uColor = sceGxmProgramFindParameterByName(colorFragmentProgramGxp, "uColor"); // vec4
|
||||||
@ -900,6 +952,108 @@ GXMMeshCacheEntry GXMRenderer::GXMUploadMesh(const MeshGroup& meshGroup)
|
|||||||
cache.indexBuffer = indexBuffer;
|
cache.indexBuffer = indexBuffer;
|
||||||
cache.indexCount = indices.size();
|
cache.indexCount = indices.size();
|
||||||
|
|
||||||
|
#ifdef GXM_PRECOMPUTE
|
||||||
|
bool isOpaque = meshGroup.color.a == 0xff;
|
||||||
|
const SceGxmTexture* texture = nullptr;
|
||||||
|
if(meshGroup.texture) {
|
||||||
|
Uint32 textureId = GetTextureId(meshGroup.texture, false);
|
||||||
|
texture = &this->m_textures[textureId].gxmTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SceGxmProgram* fragmentProgramGxp;
|
||||||
|
const SceGxmFragmentProgram *fragmentProgram;
|
||||||
|
if(texture) {
|
||||||
|
fragmentProgramGxp = mainTextureFragmentProgramGxp;
|
||||||
|
fragmentProgram = isOpaque ? this->opaqueTextureFragmentProgram : this->blendedTextureFragmentProgram;
|
||||||
|
} else {
|
||||||
|
fragmentProgramGxp = mainColorFragmentProgramGxp;
|
||||||
|
fragmentProgram = isOpaque ? this->opaqueColorFragmentProgram : this->blendedColorFragmentProgram;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get sizes
|
||||||
|
const size_t drawSize = ALIGN(sceGxmGetPrecomputedDrawSize(this->mainVertexProgram), SCE_GXM_PRECOMPUTED_ALIGNMENT);
|
||||||
|
const size_t vertexStateSize = ALIGN(sceGxmGetPrecomputedVertexStateSize(this->mainVertexProgram), SCE_GXM_PRECOMPUTED_ALIGNMENT);
|
||||||
|
const size_t fragmentStateSize = ALIGN(sceGxmGetPrecomputedFragmentStateSize(fragmentProgram), SCE_GXM_PRECOMPUTED_ALIGNMENT);
|
||||||
|
const size_t precomputeDataSize =
|
||||||
|
drawSize +
|
||||||
|
vertexStateSize * GXM_VERTEX_BUFFER_COUNT +
|
||||||
|
fragmentStateSize * GXM_FRAGMENT_BUFFER_COUNT;
|
||||||
|
|
||||||
|
const size_t vertexDefaultBufferSize = sceGxmProgramGetDefaultUniformBufferSize(mainVertexProgramGxp);
|
||||||
|
const size_t fragmentDefaultBufferSize = sceGxmProgramGetDefaultUniformBufferSize(fragmentProgramGxp);
|
||||||
|
const size_t uniformBuffersSize =
|
||||||
|
vertexDefaultBufferSize * GXM_VERTEX_BUFFER_COUNT;
|
||||||
|
fragmentStateSize * GXM_FRAGMENT_BUFFER_COUNT;
|
||||||
|
|
||||||
|
sceClibPrintf("drawSize: %d\n", drawSize);
|
||||||
|
sceClibPrintf("vertexStateSize: %d\n", vertexStateSize);
|
||||||
|
sceClibPrintf("fragmentStateSize: %d\n", fragmentStateSize);
|
||||||
|
sceClibPrintf("precomputeDataSize: %d\n", precomputeDataSize);
|
||||||
|
sceClibPrintf("vertexDefaultBufferSize: %d\n", vertexDefaultBufferSize);
|
||||||
|
sceClibPrintf("fragmentDefaultBufferSize: %d\n", fragmentDefaultBufferSize);
|
||||||
|
sceClibPrintf("uniformBuffersSize: %d\n", uniformBuffersSize);
|
||||||
|
|
||||||
|
// allocate the precompute buffer, combined for all
|
||||||
|
uint8_t* precomputeData = (uint8_t*)cdram_alloc(precomputeDataSize, SCE_GXM_PRECOMPUTED_ALIGNMENT);
|
||||||
|
cache.precomputeData = precomputeData;
|
||||||
|
|
||||||
|
uint8_t* uniformBuffers = (uint8_t*)cdram_alloc(uniformBuffersSize, 4);
|
||||||
|
cache.uniformBuffers = uniformBuffers;
|
||||||
|
|
||||||
|
// init precomputed draw
|
||||||
|
SCE_ERR(sceGxmPrecomputedDrawInit,
|
||||||
|
&cache.drawState,
|
||||||
|
this->mainVertexProgram,
|
||||||
|
precomputeData
|
||||||
|
);
|
||||||
|
void* vertexStreams[] = { vertexBuffer };
|
||||||
|
sceGxmPrecomputedDrawSetAllVertexStreams(&cache.drawState, vertexStreams);
|
||||||
|
sceGxmPrecomputedDrawSetParams(
|
||||||
|
&cache.drawState,
|
||||||
|
SCE_GXM_PRIMITIVE_TRIANGLES,
|
||||||
|
SCE_GXM_INDEX_FORMAT_U16,
|
||||||
|
indexBuffer,
|
||||||
|
indices.size()
|
||||||
|
);
|
||||||
|
precomputeData += drawSize;
|
||||||
|
|
||||||
|
// init precomputed vertex state
|
||||||
|
for(int bufferIndex = 0; bufferIndex < GXM_VERTEX_BUFFER_COUNT; bufferIndex++) {
|
||||||
|
SCE_ERR(sceGxmPrecomputedVertexStateInit,
|
||||||
|
&cache.vertexState[bufferIndex],
|
||||||
|
this->mainVertexProgram,
|
||||||
|
precomputeData
|
||||||
|
);
|
||||||
|
sceGxmPrecomputedVertexStateSetDefaultUniformBuffer(
|
||||||
|
&cache.vertexState[bufferIndex],
|
||||||
|
uniformBuffers
|
||||||
|
);
|
||||||
|
precomputeData += vertexStateSize;
|
||||||
|
uniformBuffers += vertexDefaultBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init precomputed fragment state
|
||||||
|
for(int bufferIndex = 0; bufferIndex < GXM_FRAGMENT_BUFFER_COUNT; bufferIndex++) {
|
||||||
|
SCE_ERR(sceGxmPrecomputedFragmentStateInit,
|
||||||
|
&cache.fragmentState[bufferIndex],
|
||||||
|
fragmentProgram,
|
||||||
|
precomputeData
|
||||||
|
);
|
||||||
|
if(texture) {
|
||||||
|
sceGxmPrecomputedFragmentStateSetTexture(
|
||||||
|
&cache.fragmentState[bufferIndex],
|
||||||
|
0, texture
|
||||||
|
);
|
||||||
|
}
|
||||||
|
sceGxmPrecomputedFragmentStateSetDefaultUniformBuffer(
|
||||||
|
&cache.fragmentState[bufferIndex],
|
||||||
|
uniformBuffers
|
||||||
|
);
|
||||||
|
precomputeData += fragmentStateSize;
|
||||||
|
uniformBuffers += fragmentDefaultBufferSize;
|
||||||
|
}
|
||||||
|
assert(precomputeData - (uint8_t*)cache.precomputeData <= precomputeDataSize);
|
||||||
|
#endif
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1033,25 +1187,35 @@ HRESULT GXMRenderer::BeginFrame()
|
|||||||
this->StartScene();
|
this->StartScene();
|
||||||
|
|
||||||
auto lightData = this->LightsBuffer();
|
auto lightData = this->LightsBuffer();
|
||||||
int lightCount = std::min(static_cast<int>(m_lights.size()), 3);
|
int i = 0;
|
||||||
for (int i = 0; i < lightCount; ++i) {
|
for(const auto& light : m_lights) {
|
||||||
const auto& src = m_lights[i];
|
if(!light.directional && !light.positional) {
|
||||||
lightData->lights[i].color[0] = src.color.r;
|
lightData->ambientLight[0] = light.color.r;
|
||||||
lightData->lights[i].color[1] = src.color.g;
|
lightData->ambientLight[1] = light.color.g;
|
||||||
lightData->lights[i].color[2] = src.color.b;
|
lightData->ambientLight[2] = light.color.b;
|
||||||
lightData->lights[i].color[3] = src.color.a;
|
continue;
|
||||||
|
}
|
||||||
|
if(i == 2) {
|
||||||
|
sceClibPrintf("light overflow\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
lightData->lights[i].position[0] = src.position.x;
|
lightData->lights[i].color[0] = light.color.r;
|
||||||
lightData->lights[i].position[1] = src.position.y;
|
lightData->lights[i].color[1] = light.color.g;
|
||||||
lightData->lights[i].position[2] = src.position.z;
|
lightData->lights[i].color[2] = light.color.b;
|
||||||
lightData->lights[i].position[3] = src.positional;
|
lightData->lights[i].color[3] = light.color.a;
|
||||||
|
|
||||||
lightData->lights[i].direction[0] = src.direction.x;
|
lightData->lights[i].position[0] = light.position.x;
|
||||||
lightData->lights[i].direction[1] = src.direction.y;
|
lightData->lights[i].position[1] = light.position.y;
|
||||||
lightData->lights[i].direction[2] = src.direction.z;
|
lightData->lights[i].position[2] = light.position.z;
|
||||||
lightData->lights[i].direction[3] = src.directional;
|
lightData->lights[i].position[3] = light.positional;
|
||||||
|
|
||||||
|
lightData->lights[i].direction[0] = light.direction.x;
|
||||||
|
lightData->lights[i].direction[1] = light.direction.y;
|
||||||
|
lightData->lights[i].direction[2] = light.direction.z;
|
||||||
|
lightData->lights[i].direction[3] = light.directional;
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
lightData->lightCount = lightCount;
|
|
||||||
sceGxmSetFragmentUniformBuffer(this->context, 0, lightData);
|
sceGxmSetFragmentUniformBuffer(this->context, 0, lightData);
|
||||||
|
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
@ -1100,21 +1264,19 @@ void GXMRenderer::SubmitDraw(
|
|||||||
sceGxmPushUserMarker(this->context, marker);
|
sceGxmPushUserMarker(this->context, marker);
|
||||||
|
|
||||||
sceGxmSetVertexProgram(this->context, this->mainVertexProgram);
|
sceGxmSetVertexProgram(this->context, this->mainVertexProgram);
|
||||||
if (this->transparencyEnabled) {
|
|
||||||
sceGxmSetFragmentProgram(this->context, this->transparentFragmentProgram);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sceGxmSetFragmentProgram(this->context, this->opaqueFragmentProgram);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* vertUniforms;
|
bool textured = appearance.textureId != NO_TEXTURE_ID;
|
||||||
void* fragUniforms;
|
|
||||||
sceGxmReserveVertexDefaultUniformBuffer(this->context, &vertUniforms);
|
|
||||||
sceGxmReserveFragmentDefaultUniformBuffer(this->context, &fragUniforms);
|
|
||||||
|
|
||||||
SET_UNIFORM(vertUniforms, this->uModelViewMatrix, modelViewMatrix);
|
const SceGxmFragmentProgram *fragmentProgram;
|
||||||
SET_UNIFORM(vertUniforms, this->uProjectionMatrix, m_projection);
|
if(this->transparencyEnabled) {
|
||||||
sceGxmSetUniformDataF(vertUniforms, this->uNormalMatrix, 0, 9, static_cast<const float*>(normalMatrix[0]));
|
fragmentProgram = textured ? this->blendedTextureFragmentProgram : this->blendedColorFragmentProgram;
|
||||||
|
} else {
|
||||||
|
fragmentProgram = textured ? this->opaqueTextureFragmentProgram : this->opaqueColorFragmentProgram;
|
||||||
|
}
|
||||||
|
sceGxmSetFragmentProgram(this->context, fragmentProgram);
|
||||||
|
|
||||||
|
const SceGxmProgramParameter* uColor = textured ? this->texture_uColor : this->color_uColor;
|
||||||
|
const SceGxmProgramParameter* uShininess = textured ? this->texture_uShininess : this->color_uShininess;
|
||||||
|
|
||||||
float color[4] = {
|
float color[4] = {
|
||||||
appearance.color.r / 255.0f,
|
appearance.color.r / 255.0f,
|
||||||
@ -1122,19 +1284,39 @@ void GXMRenderer::SubmitDraw(
|
|||||||
appearance.color.b / 255.0f,
|
appearance.color.b / 255.0f,
|
||||||
appearance.color.a / 255.0f
|
appearance.color.a / 255.0f
|
||||||
};
|
};
|
||||||
SET_UNIFORM(fragUniforms, this->uColor, color);
|
|
||||||
SET_UNIFORM(fragUniforms, this->uShininess, appearance.shininess);
|
|
||||||
|
|
||||||
int useTexture = appearance.textureId != NO_TEXTURE_ID ? 1 : 0;
|
void* vertUniforms;
|
||||||
SET_UNIFORM(fragUniforms, this->uUseTexture, useTexture);
|
void* fragUniforms;
|
||||||
if (useTexture) {
|
#ifdef GXM_PRECOMPUTE
|
||||||
|
sceGxmSetPrecomputedVertexState(this->context, &mesh.vertexState[this->currentVertexBufferIndex]);
|
||||||
|
sceGxmSetPrecomputedFragmentState(this->context, &mesh.fragmentState[this->currentFragmentBufferIndex]);
|
||||||
|
vertUniforms = sceGxmPrecomputedVertexStateGetDefaultUniformBuffer(&mesh.vertexState[this->currentVertexBufferIndex]);
|
||||||
|
fragUniforms = sceGxmPrecomputedFragmentStateGetDefaultUniformBuffer(&mesh.fragmentState[this->currentFragmentBufferIndex]);
|
||||||
|
#else
|
||||||
|
sceGxmReserveVertexDefaultUniformBuffer(this->context, &vertUniforms);
|
||||||
|
sceGxmReserveFragmentDefaultUniformBuffer(this->context, &fragUniforms);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SET_UNIFORM(vertUniforms, this->uModelViewMatrix, modelViewMatrix);
|
||||||
|
SET_UNIFORM(vertUniforms, this->uProjectionMatrix, m_projection);
|
||||||
|
sceGxmSetUniformDataF(vertUniforms, this->uNormalMatrix, 0, 9, static_cast<const float*>(normalMatrix[0]));
|
||||||
|
|
||||||
|
SET_UNIFORM(fragUniforms, uColor, color);
|
||||||
|
SET_UNIFORM(fragUniforms, uShininess, appearance.shininess);
|
||||||
|
|
||||||
|
if (textured) {
|
||||||
auto& texture = m_textures[appearance.textureId];
|
auto& texture = m_textures[appearance.textureId];
|
||||||
sceGxmSetFragmentTexture(this->context, 0, &texture.gxmTexture);
|
sceGxmSetFragmentTexture(this->context, 0, &texture.gxmTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef GXM_PRECOMPUTE
|
||||||
|
sceGxmDrawPrecomputed(this->context, &mesh.drawState);
|
||||||
|
sceGxmSetPrecomputedVertexState(this->context, NULL);
|
||||||
|
sceGxmSetPrecomputedFragmentState(this->context, NULL);
|
||||||
|
#else
|
||||||
sceGxmSetVertexStream(this->context, 0, mesh.vertexBuffer);
|
sceGxmSetVertexStream(this->context, 0, mesh.vertexBuffer);
|
||||||
sceGxmDraw(this->context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, mesh.indexBuffer, mesh.indexCount);
|
sceGxmDraw(this->context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, mesh.indexBuffer, mesh.indexCount);
|
||||||
|
#endif
|
||||||
sceGxmPopUserMarker(this->context);
|
sceGxmPopUserMarker(this->context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,2 +1,3 @@
|
|||||||
*.exe
|
*.exe
|
||||||
cache/
|
cache/
|
||||||
|
*.perf.txt
|
||||||
@ -1,9 +1,13 @@
|
|||||||
shaders += main.frag.gxp main.vert.gxp
|
shaders += main.vert.gxp
|
||||||
shaders += color.frag.gxp image.frag.gxp
|
shaders += color.frag.gxp image.frag.gxp
|
||||||
|
shaders += main.color.frag.gxp main.texture.frag.gxp
|
||||||
|
|
||||||
|
PERFS = $(shaders:.gxp=.perf.txt)
|
||||||
|
|
||||||
all: $(shaders)
|
all: $(shaders)
|
||||||
|
perfs: $(PERFS)
|
||||||
|
|
||||||
CGCFLAGS = -Wperf -cache -cachedir cache
|
CGCFLAGS = -Wperf -cache -cachedir cache -W4 -Wsuppress=5206,5203
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
mkdir -p cache
|
mkdir -p cache
|
||||||
@ -13,3 +17,12 @@ cache:
|
|||||||
|
|
||||||
%.frag.gxp: %.frag.cg | cache
|
%.frag.gxp: %.frag.cg | cache
|
||||||
./psp2cgc.exe $(CGCFLAGS) -profile sce_fp_psp2 $< -o $@
|
./psp2cgc.exe $(CGCFLAGS) -profile sce_fp_psp2 $< -o $@
|
||||||
|
|
||||||
|
main.color.frag.gxp: main.frag.cg | cache
|
||||||
|
./psp2cgc.exe $(CGCFLAGS) -profile sce_fp_psp2 $< -o $@
|
||||||
|
|
||||||
|
main.texture.frag.gxp: main.frag.cg | cache
|
||||||
|
./psp2cgc.exe $(CGCFLAGS) -DTEXTURED=1 -profile sce_fp_psp2 $< -o $@
|
||||||
|
|
||||||
|
%.perf.txt: %.gxp
|
||||||
|
./psp2shaderperf.exe -disasm $< > $@
|
||||||
|
|||||||
Binary file not shown.
BIN
miniwin/src/d3drm/backends/gxm/shaders/main.color.frag.gxp
Normal file
BIN
miniwin/src/d3drm/backends/gxm/shaders/main.color.frag.gxp
Normal file
Binary file not shown.
@ -10,11 +10,10 @@ void main(
|
|||||||
float3 vNormal : TEXCOORD2,
|
float3 vNormal : TEXCOORD2,
|
||||||
float2 vTexCoord : TEXCOORD3,
|
float2 vTexCoord : TEXCOORD3,
|
||||||
|
|
||||||
uniform __nostrip SceneLight uLights[3] : BUFFER[0],
|
uniform __nostrip SceneLight uLights[2] : BUFFER[0],
|
||||||
uniform __nostrip int uLightCount : BUFFER[0],
|
uniform __nostrip float3 uAmbientLight : BUFFER[0],
|
||||||
uniform __nostrip float uShininess,
|
uniform __nostrip float uShininess,
|
||||||
uniform __nostrip float4 uColor,
|
uniform __nostrip float4 uColor,
|
||||||
uniform __nostrip int uUseTexture,
|
|
||||||
uniform __nostrip sampler2D uTexture,
|
uniform __nostrip sampler2D uTexture,
|
||||||
|
|
||||||
out float4 outColor : COLOR
|
out float4 outColor : COLOR
|
||||||
@ -22,46 +21,38 @@ void main(
|
|||||||
float3 diffuse = float3(0.0, 0.0, 0.0);
|
float3 diffuse = float3(0.0, 0.0, 0.0);
|
||||||
float3 specular = float3(0.0, 0.0, 0.0);
|
float3 specular = float3(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
for (int i = 0; i < uLightCount; ++i) {
|
float3 viewVec = normalize(-vViewPos); // Assuming camera at origin
|
||||||
float3 lightColor = uLights[i].color.rgb;
|
|
||||||
|
|
||||||
// ambient
|
diffuse += uAmbientLight;
|
||||||
if (uLights[i].position.w == 0.0 && uLights[i].direction.w == 0.0) {
|
|
||||||
diffuse += lightColor;
|
for (int i = 0; i < 2; ++i) {
|
||||||
continue;
|
float3 lightColor = uLights[i].color.rgb;
|
||||||
}
|
float isDirectional = uLights[i].direction.w;
|
||||||
|
float isPositional = uLights[i].position.w;
|
||||||
|
|
||||||
// directional
|
// directional
|
||||||
float3 lightVec;
|
float3 pointLightVec = uLights[i].position.xyz - vViewPos;
|
||||||
if (uLights[i].direction.w == 1.0) {
|
float3 directionalLightVec = -uLights[i].direction.xyz;
|
||||||
lightVec = -normalize(uLights[i].direction.xyz);
|
float3 lightVec = normalize(lerp(pointLightVec, directionalLightVec, isDirectional));
|
||||||
} else { // point
|
|
||||||
lightVec = normalize(uLights[i].position.xyz - vViewPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Diffuse contribution
|
||||||
float dotNL = max(dot(vNormal, lightVec), 0.0);
|
float dotNL = max(dot(vNormal, lightVec), 0.0);
|
||||||
if (dotNL > 0.0) {
|
diffuse += dotNL * lightColor;
|
||||||
// Diffuse contribution
|
|
||||||
diffuse += dotNL * lightColor;
|
|
||||||
|
|
||||||
// Specular
|
// Specular
|
||||||
if (uShininess > 0.0) {
|
//float enableSpec = (dotNL > 0.0) * (uShininess > 0.0);
|
||||||
float3 viewVec = normalize(-vViewPos); // Assuming camera at origin
|
if (dotNL > 0.0 && uShininess > 0.0) {
|
||||||
float3 halfVec = normalize(lightVec + viewVec);
|
float3 halfVec = normalize(lightVec + viewVec);
|
||||||
float dotNH = max(dot(vNormal, halfVec), 0.0);
|
float dotNH = max(dot(vNormal, halfVec), 0.0);
|
||||||
float spec = pow(dotNH, uShininess);
|
float spec = pow(dotNH, uShininess);
|
||||||
specular += spec * lightColor;
|
specular += spec * lightColor;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outColor = uColor;
|
|
||||||
outColor.rgb = clamp(diffuse * uColor.rgb + specular, 0.0, 1.0);
|
outColor.rgb = clamp(diffuse * uColor.rgb + specular, 0.0, 1.0);
|
||||||
if (uUseTexture != 0) {
|
outColor.a = uColor.a;
|
||||||
float4 texel = tex2D(uTexture, vTexCoord);
|
#if TEXTURED
|
||||||
outColor.rgb *= texel.rgb;
|
float4 texel = tex2D(uTexture, vTexCoord);
|
||||||
outColor.rgb = clamp(outColor.rgb, 0.0, 1.0);
|
outColor.rgb *= texel.rgb;
|
||||||
}
|
#endif
|
||||||
|
}
|
||||||
//outColor = float4(vNormal, 1.0);
|
|
||||||
}
|
|
||||||
|
|||||||
Binary file not shown.
BIN
miniwin/src/d3drm/backends/gxm/shaders/main.texture.frag.gxp
Normal file
BIN
miniwin/src/d3drm/backends/gxm/shaders/main.texture.frag.gxp
Normal file
Binary file not shown.
@ -20,6 +20,8 @@ DEFINE_GUID(GXM_GUID, 0x682656F3, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|||||||
#define GXM_VERTEX_BUFFER_COUNT 2
|
#define GXM_VERTEX_BUFFER_COUNT 2
|
||||||
#define GXM_FRAGMENT_BUFFER_COUNT 3
|
#define GXM_FRAGMENT_BUFFER_COUNT 3
|
||||||
|
|
||||||
|
//#define GXM_PRECOMPUTE
|
||||||
|
|
||||||
struct GXMTextureCacheEntry {
|
struct GXMTextureCacheEntry {
|
||||||
IDirect3DRMTexture* texture;
|
IDirect3DRMTexture* texture;
|
||||||
Uint32 version;
|
Uint32 version;
|
||||||
@ -35,6 +37,14 @@ struct GXMMeshCacheEntry {
|
|||||||
void* vertexBuffer;
|
void* vertexBuffer;
|
||||||
void* indexBuffer;
|
void* indexBuffer;
|
||||||
uint16_t indexCount;
|
uint16_t indexCount;
|
||||||
|
|
||||||
|
#ifdef GXM_PRECOMPUTE
|
||||||
|
void* precomputeData;
|
||||||
|
void* uniformBuffers;
|
||||||
|
SceGxmPrecomputedVertexState vertexState[GXM_VERTEX_BUFFER_COUNT];
|
||||||
|
SceGxmPrecomputedFragmentState fragmentState[GXM_FRAGMENT_BUFFER_COUNT];
|
||||||
|
SceGxmPrecomputedDraw drawState;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct GXMDisplayData {
|
typedef struct GXMDisplayData {
|
||||||
@ -50,8 +60,8 @@ struct SceneLightGXM {
|
|||||||
static_assert(sizeof(SceneLightGXM) == 4*4*3);
|
static_assert(sizeof(SceneLightGXM) == 4*4*3);
|
||||||
|
|
||||||
struct GXMSceneLightUniform {
|
struct GXMSceneLightUniform {
|
||||||
SceneLightGXM lights[3];
|
SceneLightGXM lights[2];
|
||||||
int lightCount;
|
float ambientLight[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -175,15 +185,20 @@ class GXMRenderer : public Direct3DRMRenderer {
|
|||||||
|
|
||||||
// shader
|
// shader
|
||||||
SceGxmShaderPatcherId mainVertexProgramId;
|
SceGxmShaderPatcherId mainVertexProgramId;
|
||||||
SceGxmShaderPatcherId mainFragmentProgramId;
|
SceGxmShaderPatcherId mainColorFragmentProgramId;
|
||||||
|
SceGxmShaderPatcherId mainTextureFragmentProgramId;
|
||||||
SceGxmShaderPatcherId imageFragmentProgramId;
|
SceGxmShaderPatcherId imageFragmentProgramId;
|
||||||
SceGxmShaderPatcherId colorFragmentProgramId;
|
SceGxmShaderPatcherId colorFragmentProgramId;
|
||||||
|
|
||||||
SceGxmVertexProgram* mainVertexProgram; // 3d vert
|
SceGxmVertexProgram* mainVertexProgram;
|
||||||
SceGxmFragmentProgram* opaqueFragmentProgram; // 3d with no transparency
|
// with lighting
|
||||||
SceGxmFragmentProgram* transparentFragmentProgram; // 3d with transparency
|
SceGxmFragmentProgram* opaqueColorFragmentProgram;
|
||||||
SceGxmFragmentProgram* imageFragmentProgram; // 2d images, no lighting
|
SceGxmFragmentProgram* blendedColorFragmentProgram;
|
||||||
SceGxmFragmentProgram* colorFragmentProgram; // 2d color, no lighting
|
SceGxmFragmentProgram* opaqueTextureFragmentProgram;
|
||||||
|
SceGxmFragmentProgram* blendedTextureFragmentProgram;
|
||||||
|
// no lighting
|
||||||
|
SceGxmFragmentProgram* imageFragmentProgram;
|
||||||
|
SceGxmFragmentProgram* colorFragmentProgram;
|
||||||
|
|
||||||
// main shader vertex uniforms
|
// main shader vertex uniforms
|
||||||
const SceGxmProgramParameter* uModelViewMatrix;
|
const SceGxmProgramParameter* uModelViewMatrix;
|
||||||
@ -191,11 +206,14 @@ class GXMRenderer : public Direct3DRMRenderer {
|
|||||||
const SceGxmProgramParameter* uProjectionMatrix;
|
const SceGxmProgramParameter* uProjectionMatrix;
|
||||||
|
|
||||||
// main shader fragment uniforms
|
// main shader fragment uniforms
|
||||||
const SceGxmProgramParameter* uLights;
|
const SceGxmProgramParameter* color_uLights;
|
||||||
const SceGxmProgramParameter* uLightCount;
|
const SceGxmProgramParameter* color_uAmbientLight;
|
||||||
const SceGxmProgramParameter* uShininess;
|
const SceGxmProgramParameter* color_uShininess;
|
||||||
const SceGxmProgramParameter* uColor;
|
const SceGxmProgramParameter* color_uColor;
|
||||||
const SceGxmProgramParameter* uUseTexture;
|
const SceGxmProgramParameter* texture_uLights;
|
||||||
|
const SceGxmProgramParameter* texture_uAmbientLight;
|
||||||
|
const SceGxmProgramParameter* texture_uShininess;
|
||||||
|
const SceGxmProgramParameter* texture_uColor;
|
||||||
|
|
||||||
// color shader frament uniforms
|
// color shader frament uniforms
|
||||||
const SceGxmProgramParameter* colorShader_uColor;
|
const SceGxmProgramParameter* colorShader_uColor;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user