mirror of
https://github.com/libretro/RetroArch
synced 2025-04-01 13:20:43 +00:00
Merge pull request #6073 from aliaspider/master
(WIIU) improve support for custom shaders.
This commit is contained in:
commit
ae9e13324d
@ -86,8 +86,8 @@ typedef struct
|
||||
struct
|
||||
{
|
||||
GFDFile* gfd;
|
||||
float* vs_ubo;
|
||||
float* ps_ubo;
|
||||
float* vs_ubos[2];
|
||||
float* ps_ubos[2];
|
||||
GX2Texture texture;
|
||||
GX2ColorBuffer color_buffer;
|
||||
}pass[GFX_MAX_SHADERS];
|
||||
|
@ -53,7 +53,8 @@ static const wiiu_render_mode_t wiiu_render_mode_map[] =
|
||||
{1920, 1080, GX2_TV_RENDER_MODE_WIDE_1080P} /* GX2_TV_SCAN_MODE_1080P */
|
||||
};
|
||||
|
||||
static void wiiu_set_tex_coords(frame_vertex_t *v, GX2Texture *texture, float u0, float v0, float u1, float v1,
|
||||
static void wiiu_set_tex_coords(frame_vertex_t *v, GX2Texture *texture, float u0, float v0,
|
||||
float u1, float v1,
|
||||
unsigned rotation)
|
||||
{
|
||||
v[0].coord.u = u0 / texture->surface.width;
|
||||
@ -224,7 +225,7 @@ static void *wiiu_gfx_init(const video_info_t *video,
|
||||
|
||||
/* setup scanbuffers */
|
||||
wiiu->render_mode = wiiu_render_mode_map[GX2GetSystemTVScanMode()];
|
||||
// wiiu->render_mode = wiiu_render_mode_map[GX2_TV_SCAN_MODE_480P];
|
||||
wiiu->render_mode = wiiu_render_mode_map[GX2_TV_SCAN_MODE_480P];
|
||||
GX2CalcTVSize(wiiu->render_mode.mode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8,
|
||||
GX2_BUFFERING_MODE_DOUBLE, &size, &tmp);
|
||||
|
||||
@ -263,18 +264,21 @@ static void *wiiu_gfx_init(const video_info_t *video,
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->color_buffer.surface.image,
|
||||
wiiu->color_buffer.surface.imageSize);
|
||||
|
||||
wiiu->ctx_state = (GX2ContextState *)MEM2_alloc(sizeof(GX2ContextState), GX2_CONTEXT_STATE_ALIGNMENT);
|
||||
wiiu->ctx_state = (GX2ContextState *)MEM2_alloc(sizeof(GX2ContextState),
|
||||
GX2_CONTEXT_STATE_ALIGNMENT);
|
||||
GX2SetupContextStateEx(wiiu->ctx_state, GX2_TRUE);
|
||||
|
||||
GX2SetContextState(wiiu->ctx_state);
|
||||
GX2SetColorBuffer(&wiiu->color_buffer, GX2_RENDER_TARGET_0);
|
||||
GX2SetViewport(0.0f, 0.0f, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height, 0.0f, 1.0f);
|
||||
GX2SetViewport(0.0f, 0.0f, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height,
|
||||
0.0f, 1.0f);
|
||||
GX2SetScissor(0, 0, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);
|
||||
GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_ALWAYS);
|
||||
GX2SetColorControl(GX2_LOGIC_OP_COPY, 1, GX2_DISABLE, GX2_ENABLE);
|
||||
GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA,
|
||||
GX2_BLEND_COMBINE_MODE_ADD,
|
||||
GX2_ENABLE, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD);
|
||||
GX2_ENABLE, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA,
|
||||
GX2_BLEND_COMBINE_MODE_ADD);
|
||||
GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_DISABLE, GX2_DISABLE);
|
||||
|
||||
GX2InitShader(&frame_shader);
|
||||
@ -294,8 +298,10 @@ static void *wiiu_gfx_init(const video_info_t *video,
|
||||
wiiu->ubo_mvp = MEM1_alloc(sizeof(*wiiu->ubo_mvp), GX2_UNIFORM_BLOCK_ALIGNMENT);
|
||||
wiiu_set_projection(wiiu);
|
||||
|
||||
wiiu->input_ring_buffer_size = GX2CalcGeometryShaderInputRingBufferSize(sprite_shader.vs.ringItemSize);
|
||||
wiiu->output_ring_buffer_size = GX2CalcGeometryShaderOutputRingBufferSize(sprite_shader.gs.ringItemSize);
|
||||
wiiu->input_ring_buffer_size = GX2CalcGeometryShaderInputRingBufferSize(
|
||||
sprite_shader.vs.ringItemSize);
|
||||
wiiu->output_ring_buffer_size = GX2CalcGeometryShaderOutputRingBufferSize(
|
||||
sprite_shader.gs.ringItemSize);
|
||||
wiiu->input_ring_buffer = MEM1_alloc(wiiu->input_ring_buffer_size, 0x1000);
|
||||
wiiu->output_ring_buffer = MEM1_alloc(wiiu->output_ring_buffer_size, 0x1000);
|
||||
|
||||
@ -526,7 +532,8 @@ static void gx2_overlay_set_alpha(void *data, unsigned image, float mod)
|
||||
{
|
||||
gx2->overlay[image].alpha_mod = mod;
|
||||
gx2->overlay[image].v.color = COLOR_RGBA(0xFF, 0xFF, 0xFF, 0xFF * gx2->overlay[image].alpha_mod);
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, &gx2->overlay[image].v, sizeof(gx2->overlay[image].v));
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, &gx2->overlay[image].v,
|
||||
sizeof(gx2->overlay[image].v));
|
||||
}
|
||||
}
|
||||
|
||||
@ -576,8 +583,10 @@ static void wiiu_free_shader_preset(wiiu_video_t *wiiu)
|
||||
for (int i = 0; i < wiiu->shader_preset->passes; i++)
|
||||
{
|
||||
gfd_free(wiiu->pass[i].gfd);
|
||||
MEM2_free(wiiu->pass[i].vs_ubo);
|
||||
MEM2_free(wiiu->pass[i].ps_ubo);
|
||||
MEM2_free(wiiu->pass[i].vs_ubos[0]);
|
||||
MEM2_free(wiiu->pass[i].vs_ubos[1]);
|
||||
MEM2_free(wiiu->pass[i].ps_ubos[0]);
|
||||
MEM2_free(wiiu->pass[i].ps_ubos[1]);
|
||||
MEM1_free(wiiu->pass[i].texture.surface.image);
|
||||
}
|
||||
|
||||
@ -641,10 +650,14 @@ static void wiiu_gfx_free(void *data)
|
||||
static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigned height)
|
||||
{
|
||||
MEM2_free(wiiu->texture.surface.image);
|
||||
if(wiiu->shader_preset)
|
||||
|
||||
if (wiiu->shader_preset)
|
||||
{
|
||||
for (int i = 0; i < wiiu->shader_preset->passes; i++)
|
||||
{
|
||||
MEM1_free(wiiu->pass[i].texture.surface.image);
|
||||
wiiu->pass[i].texture.surface.image = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize frame texture */
|
||||
@ -677,7 +690,7 @@ static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigne
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->texture.surface.image,
|
||||
wiiu->texture.surface.imageSize);
|
||||
|
||||
if(wiiu->shader_preset)
|
||||
if (wiiu->shader_preset)
|
||||
{
|
||||
for (int i = 0; i < wiiu->shader_preset->passes; i++)
|
||||
{
|
||||
@ -732,11 +745,13 @@ static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigne
|
||||
wiiu->pass[i].texture.surface.width = width;
|
||||
wiiu->pass[i].texture.surface.height = height;
|
||||
wiiu->pass[i].texture.surface.depth = 1;
|
||||
// wiiu->pass[i].texture.surface.mipLevels = 1;
|
||||
wiiu->pass[i].texture.surface.format = pass->fbo.fp_fbo? GX2_SURFACE_FORMAT_FLOAT_R32_G32_B32_A32 :
|
||||
pass->fbo.srgb_fbo? GX2_SURFACE_FORMAT_SRGB_R8_G8_B8_A8 :
|
||||
GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
||||
wiiu->pass[i].texture.surface.use = (GX2_SURFACE_USE_TEXTURE | GX2_SURFACE_USE_COLOR_BUFFER);
|
||||
// wiiu->pass[i].texture.surface.mipLevels = 1;
|
||||
wiiu->pass[i].texture.surface.format = pass->fbo.fp_fbo ?
|
||||
GX2_SURFACE_FORMAT_FLOAT_R32_G32_B32_A32 :
|
||||
pass->fbo.srgb_fbo ? GX2_SURFACE_FORMAT_SRGB_R8_G8_B8_A8 :
|
||||
GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
||||
wiiu->pass[i].texture.surface.use = (GX2_SURFACE_USE_TEXTURE |
|
||||
GX2_SURFACE_USE_COLOR_BUFFER);
|
||||
wiiu->pass[i].texture.viewNumSlices = 1;
|
||||
wiiu->pass[i].texture.compMap = GX2_COMP_SEL(_R, _G, _B, _A);
|
||||
|
||||
@ -744,7 +759,8 @@ static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigne
|
||||
GX2InitTextureRegs(&wiiu->pass[i].texture);
|
||||
|
||||
|
||||
if((i != (wiiu->shader_preset->passes - 1)) || (width != wiiu->vp.width) || (height != wiiu->vp.height))
|
||||
if ((i != (wiiu->shader_preset->passes - 1)) || (width != wiiu->vp.width)
|
||||
|| (height != wiiu->vp.height))
|
||||
{
|
||||
wiiu->pass[i].texture.surface.image = MEM1_alloc(wiiu->pass[i].texture.surface.imageSize,
|
||||
wiiu->pass[i].texture.surface.alignment);
|
||||
@ -770,6 +786,73 @@ static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigne
|
||||
return true;
|
||||
}
|
||||
|
||||
static void wiiu_gfx_update_uniform_block(wiiu_video_t *wiiu, int pass, float *ubo, int id,
|
||||
int size,
|
||||
int uniformVarCount, GX2UniformVar *uniformVars)
|
||||
{
|
||||
for (int i = 0; i < uniformVarCount; i++)
|
||||
{
|
||||
if (uniformVars[i].block != id)
|
||||
continue;
|
||||
|
||||
const char *id = strrchr(uniformVars[i].name, '.');
|
||||
|
||||
if (!id)
|
||||
continue;
|
||||
|
||||
id++;
|
||||
|
||||
float *dst = ubo + uniformVars[i].offset;
|
||||
|
||||
if (!strcmp(id, "OutputSize"))
|
||||
{
|
||||
((GX2_vec4 *)dst)->x = wiiu->pass[pass].color_buffer.surface.width;
|
||||
((GX2_vec4 *)dst)->y = wiiu->pass[pass].color_buffer.surface.height;
|
||||
((GX2_vec4 *)dst)->z = 1.0f / wiiu->pass[pass].color_buffer.surface.width;
|
||||
((GX2_vec4 *)dst)->w = 1.0f / wiiu->pass[pass].color_buffer.surface.height;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(id, "OriginalSize"))
|
||||
{
|
||||
((GX2_vec4 *)dst)->x = wiiu->texture.surface.width;
|
||||
((GX2_vec4 *)dst)->y = wiiu->texture.surface.height;
|
||||
((GX2_vec4 *)dst)->z = 1.0f / wiiu->texture.surface.width;
|
||||
((GX2_vec4 *)dst)->w = 1.0f / wiiu->texture.surface.height;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(id, "SourceSize"))
|
||||
{
|
||||
GX2Surface *source = (pass > 0) ? &wiiu->pass[pass - 1].texture.surface : &wiiu->texture.surface;
|
||||
((GX2_vec4 *)dst)->x = source->width;
|
||||
((GX2_vec4 *)dst)->y = source->height;
|
||||
((GX2_vec4 *)dst)->z = 1.0f / source->width;
|
||||
((GX2_vec4 *)dst)->w = 1.0f / source->height;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(id, "MVP"))
|
||||
{
|
||||
memcpy(dst, wiiu->ubo_mvp, sizeof(*wiiu->ubo_mvp));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
for (int k = 0; k < wiiu->shader_preset->num_parameters; k++)
|
||||
{
|
||||
if (!strcmp(id, wiiu->shader_preset->parameters[k].id))
|
||||
{
|
||||
*dst = wiiu->shader_preset->parameters[k].current;
|
||||
*(u32 *)dst = __builtin_bswap32(*(u32 *)dst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, ubo, size);
|
||||
}
|
||||
|
||||
static bool wiiu_gfx_frame(void *data, const void *frame,
|
||||
unsigned width, unsigned height, uint64_t frame_count,
|
||||
@ -842,8 +925,8 @@ static bool wiiu_gfx_frame(void *data, const void *frame,
|
||||
|
||||
if (frame)
|
||||
{
|
||||
if((width != wiiu->texture.surface.width) ||
|
||||
(height != wiiu->texture.surface.height))
|
||||
if ((width != wiiu->texture.surface.width) ||
|
||||
(height != wiiu->texture.surface.height))
|
||||
wiiu_init_frame_textures(wiiu, width, height);
|
||||
|
||||
wiiu->width = width;
|
||||
@ -892,105 +975,51 @@ static bool wiiu_gfx_frame(void *data, const void *frame,
|
||||
GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK);
|
||||
|
||||
GX2SetFetchShader(&frame_shader.fs);
|
||||
GX2SetVertexUniformBlock(frame_shader.vs.uniformBlocks[0].offset, frame_shader.vs.uniformBlocks[0].size, wiiu->ubo_mvp);
|
||||
GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->v), sizeof(*wiiu->v), wiiu->v);
|
||||
|
||||
GX2Texture *texture = &wiiu->texture;
|
||||
|
||||
if (wiiu->shader_preset && !wiiu->pass[0].texture.surface.image)
|
||||
wiiu_init_frame_textures(wiiu, width, height);
|
||||
|
||||
if (wiiu->shader_preset)
|
||||
{
|
||||
if(!wiiu->pass[0].texture.surface.image)
|
||||
wiiu_init_frame_textures(wiiu, width, height);
|
||||
|
||||
for (int i = 0; i < wiiu->shader_preset->passes; i++)
|
||||
{
|
||||
|
||||
GX2SetVertexShader(wiiu->pass[i].gfd->vs);
|
||||
GX2SetPixelShader(wiiu->pass[i].gfd->ps);
|
||||
|
||||
// if (wiiu->pass[i].gfd->vs->uniformBlockCount > 0)
|
||||
// GX2SetVertexUniformBlock(wiiu->pass[i].gfd->vs->uniformBlocks[0].offset, wiiu->pass[i].gfd->vs->uniformBlocks[0].size, wiiu->ubo_mvp);
|
||||
|
||||
// GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->v), sizeof(*wiiu->v), wiiu->v);
|
||||
|
||||
// if(wiiu->pass[i].vs_ubo)
|
||||
// GX2SetVertexUniformBlock(wiiu->pass[i].gfd->vs->uniformBlocks[1].offset,
|
||||
// wiiu->pass[i].gfd->vs->uniformBlocks[1].size,
|
||||
// wiiu->pass[i].vs_ubo);
|
||||
|
||||
if (wiiu->pass[i].ps_ubo)
|
||||
for (int j = 0; j < 2 && j < wiiu->pass[i].gfd->vs->uniformBlockCount; j++)
|
||||
{
|
||||
for (int j = 0; j < wiiu->pass[i].gfd->ps->uniformVarCount; j++)
|
||||
{
|
||||
if (wiiu->pass[i].gfd->ps->uniformVars[j].block != 0)
|
||||
continue;
|
||||
|
||||
const char *id = strrchr(wiiu->pass[i].gfd->ps->uniformVars[j].name, '.');
|
||||
|
||||
if (!id)
|
||||
continue;
|
||||
|
||||
id++;
|
||||
|
||||
float *dst = wiiu->pass[i].ps_ubo + wiiu->pass[i].gfd->ps->uniformVars[j].offset;
|
||||
|
||||
if (!strcmp(id, "OutputSize"))
|
||||
{
|
||||
((GX2_vec4 *)dst)->x = wiiu->pass[i].color_buffer.surface.width;
|
||||
((GX2_vec4 *)dst)->y = wiiu->pass[i].color_buffer.surface.height;
|
||||
((GX2_vec4 *)dst)->z = 1.0f / wiiu->pass[i].color_buffer.surface.width;
|
||||
((GX2_vec4 *)dst)->w = 1.0f / wiiu->pass[i].color_buffer.surface.height;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(id, "OriginalSize"))
|
||||
{
|
||||
((GX2_vec4 *)dst)->x = wiiu->texture.surface.width;
|
||||
((GX2_vec4 *)dst)->y = wiiu->texture.surface.height;
|
||||
((GX2_vec4 *)dst)->z = 1.0f / wiiu->texture.surface.width;
|
||||
((GX2_vec4 *)dst)->w = 1.0f / wiiu->texture.surface.height;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(id, "SourceSize"))
|
||||
{
|
||||
((GX2_vec4 *)dst)->x = texture->surface.width;
|
||||
((GX2_vec4 *)dst)->y = texture->surface.height;
|
||||
((GX2_vec4 *)dst)->z = 1.0f / texture->surface.width;
|
||||
((GX2_vec4 *)dst)->w = 1.0f / texture->surface.height;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int k = 0; k < wiiu->shader_preset->num_parameters; k++)
|
||||
{
|
||||
if (!strcmp(id, wiiu->shader_preset->parameters[k].id))
|
||||
{
|
||||
*dst = wiiu->shader_preset->parameters[k].current;
|
||||
*(u32 *)dst = __builtin_bswap32(*(u32 *)dst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].ps_ubo,
|
||||
wiiu->pass[i].gfd->ps->uniformBlocks[0].size);
|
||||
|
||||
GX2SetPixelUniformBlock(wiiu->pass[i].gfd->ps->uniformBlocks[0].offset,
|
||||
wiiu->pass[i].gfd->ps->uniformBlocks[0].size, wiiu->pass[i].ps_ubo);
|
||||
wiiu_gfx_update_uniform_block(wiiu, i, wiiu->pass[i].vs_ubos[j], j,
|
||||
wiiu->pass[i].gfd->vs->uniformBlocks[j].size,
|
||||
wiiu->pass[i].gfd->vs->uniformVarCount, wiiu->pass[i].gfd->vs->uniformVars);
|
||||
GX2SetVertexUniformBlock(wiiu->pass[i].gfd->vs->uniformBlocks[j].offset,
|
||||
wiiu->pass[i].gfd->vs->uniformBlocks[j].size, wiiu->pass[i].vs_ubos[j]);
|
||||
}
|
||||
|
||||
GX2SetPixelShader(wiiu->pass[i].gfd->ps);
|
||||
for (int j = 0; j < 2 && j < wiiu->pass[i].gfd->ps->uniformBlockCount; j++)
|
||||
{
|
||||
wiiu_gfx_update_uniform_block(wiiu, i, wiiu->pass[i].ps_ubos[j], j,
|
||||
wiiu->pass[i].gfd->ps->uniformBlocks[j].size,
|
||||
wiiu->pass[i].gfd->ps->uniformVarCount, wiiu->pass[i].gfd->ps->uniformVars);
|
||||
GX2SetPixelUniformBlock(wiiu->pass[i].gfd->ps->uniformBlocks[j].offset,
|
||||
wiiu->pass[i].gfd->ps->uniformBlocks[j].size, wiiu->pass[i].ps_ubos[j]);
|
||||
}
|
||||
|
||||
GX2SetPixelTexture(texture, wiiu->pass[i].gfd->ps->samplerVars[0].location);
|
||||
GX2SetPixelSampler(wiiu->shader_preset->pass[i].filter ? &wiiu->sampler_linear : &wiiu->sampler_nearest,
|
||||
GX2SetPixelSampler(wiiu->shader_preset->pass[i].filter ? &wiiu->sampler_linear :
|
||||
&wiiu->sampler_nearest,
|
||||
wiiu->pass[i].gfd->ps->samplerVars[0].location);
|
||||
|
||||
if(wiiu->pass[i].color_buffer.surface.image)
|
||||
if (wiiu->pass[i].color_buffer.surface.image)
|
||||
{
|
||||
GX2SetColorBuffer(&wiiu->pass[i].color_buffer, GX2_RENDER_TARGET_0);
|
||||
GX2SetViewport(0.0f, 0.0f, wiiu->pass[i].color_buffer.surface.width, wiiu->pass[i].color_buffer.surface.height, 0.0f,
|
||||
GX2SetViewport(0.0f, 0.0f, wiiu->pass[i].color_buffer.surface.width,
|
||||
wiiu->pass[i].color_buffer.surface.height, 0.0f,
|
||||
1.0f);
|
||||
GX2SetScissor(0, 0, wiiu->pass[i].color_buffer.surface.width, wiiu->pass[i].color_buffer.surface.height);
|
||||
GX2SetScissor(0, 0, wiiu->pass[i].color_buffer.surface.width,
|
||||
wiiu->pass[i].color_buffer.surface.height);
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
||||
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_TEXTURE, wiiu->pass[i].texture.surface.image,
|
||||
@ -1007,9 +1036,12 @@ static bool wiiu_gfx_frame(void *data, const void *frame,
|
||||
GX2SetColorBuffer(&wiiu->color_buffer, GX2_RENDER_TARGET_0);
|
||||
}
|
||||
|
||||
if(texture)
|
||||
if (texture)
|
||||
{
|
||||
GX2SetVertexShader(&frame_shader.vs);
|
||||
GX2SetVertexUniformBlock(frame_shader.vs.uniformBlocks[0].offset,
|
||||
frame_shader.vs.uniformBlocks[0].size, wiiu->ubo_mvp);
|
||||
|
||||
GX2SetPixelShader(&frame_shader.ps);
|
||||
GX2SetPixelTexture(texture, frame_shader.ps.samplerVars[0].location);
|
||||
GX2SetPixelSampler(wiiu->smooth ? &wiiu->sampler_linear : &wiiu->sampler_nearest,
|
||||
@ -1025,11 +1057,14 @@ static bool wiiu_gfx_frame(void *data, const void *frame,
|
||||
GX2SetShader(&sprite_shader);
|
||||
GX2SetGeometryShaderInputRingBuffer(wiiu->input_ring_buffer, wiiu->input_ring_buffer_size);
|
||||
GX2SetGeometryShaderOutputRingBuffer(wiiu->output_ring_buffer, wiiu->output_ring_buffer_size);
|
||||
GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[0].offset, sprite_shader.vs.uniformBlocks[0].size,
|
||||
GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[0].offset,
|
||||
sprite_shader.vs.uniformBlocks[0].size,
|
||||
wiiu->ubo_vp);
|
||||
GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[1].offset, sprite_shader.vs.uniformBlocks[1].size,
|
||||
GX2SetVertexUniformBlock(sprite_shader.vs.uniformBlocks[1].offset,
|
||||
sprite_shader.vs.uniformBlocks[1].size,
|
||||
wiiu->ubo_tex);
|
||||
GX2SetViewport(0.0f, 0.0f, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height, 0.0f, 1.0f);
|
||||
GX2SetViewport(0.0f, 0.0f, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height,
|
||||
0.0f, 1.0f);
|
||||
GX2SetScissor(0, 0, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
@ -1177,20 +1212,22 @@ static bool wiiu_gfx_set_shader(void *data,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wiiu->pass[i].gfd->vs->uniformBlockCount > 1)
|
||||
for (int j = 0; j < 2 && j < wiiu->pass[i].gfd->vs->uniformBlockCount; j++)
|
||||
{
|
||||
wiiu->pass[i].vs_ubo = MEM2_alloc(wiiu->pass[i].gfd->vs->uniformBlocks[1].size, GX2_UNIFORM_BLOCK_ALIGNMENT);
|
||||
memset(wiiu->pass[i].vs_ubo, 0, wiiu->pass[i].gfd->vs->uniformBlocks[1].size);
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].vs_ubo,
|
||||
wiiu->pass[i].gfd->vs->uniformBlocks[1].size);
|
||||
wiiu->pass[i].vs_ubos[j] = MEM2_alloc(wiiu->pass[i].gfd->vs->uniformBlocks[j].size,
|
||||
GX2_UNIFORM_BLOCK_ALIGNMENT);
|
||||
memset(wiiu->pass[i].vs_ubos[j], 0, wiiu->pass[i].gfd->vs->uniformBlocks[j].size);
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].vs_ubos[j],
|
||||
wiiu->pass[i].gfd->vs->uniformBlocks[j].size);
|
||||
}
|
||||
|
||||
if (wiiu->pass[i].gfd->ps->uniformBlockCount > 0)
|
||||
for (int j = 0; j < 2 && j < wiiu->pass[i].gfd->ps->uniformBlockCount; j++)
|
||||
{
|
||||
wiiu->pass[i].ps_ubo = MEM2_alloc(wiiu->pass[i].gfd->ps->uniformBlocks[0].size, GX2_UNIFORM_BLOCK_ALIGNMENT);
|
||||
memset(wiiu->pass[i].ps_ubo, 0, wiiu->pass[i].gfd->ps->uniformBlocks[0].size);
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].ps_ubo,
|
||||
wiiu->pass[i].gfd->ps->uniformBlocks[0].size);
|
||||
wiiu->pass[i].ps_ubos[j] = MEM2_alloc(wiiu->pass[i].gfd->ps->uniformBlocks[j].size,
|
||||
GX2_UNIFORM_BLOCK_ALIGNMENT);
|
||||
memset(wiiu->pass[i].ps_ubos[j], 0, wiiu->pass[i].gfd->ps->uniformBlocks[j].size);
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_UNIFORM_BLOCK, wiiu->pass[i].ps_ubos[j],
|
||||
wiiu->pass[i].gfd->ps->uniformBlocks[j].size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z $1 ] ; then
|
||||
echo
|
||||
echo "usage: $0 <WiiU-ip>"
|
||||
echo
|
||||
exit 0
|
||||
fi
|
||||
|
||||
interrupt_count=0
|
||||
|
||||
trap 'if [ $interrupt_count -eq 5 ]; then exit 0; else interrupt_count=$(($interrupt_count + 1)); fi' INT
|
||||
trap 'if [ $interrupt_count -eq 20 ]; then exit 0; else interrupt_count=$(($interrupt_count + 1)); fi' INT
|
||||
|
||||
echo ===== START: `date` =====
|
||||
while true; do
|
||||
netcat -p 4405 -l
|
||||
if [ $? -ne 0 ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
echo ===== END: `date` =====
|
||||
while true; do echo; echo ========= `date` =========; echo; netcat -p 4405 -l $1; done
|
||||
|
@ -1,8 +1,80 @@
|
||||
|
||||
all: slang-convert
|
||||
GLSLC = glslc
|
||||
|
||||
slang-convert: main.c
|
||||
$(CC) $< -o $@ -g -O0 -Wall -Werror
|
||||
GSH_COMPILER = ./compiler.exe
|
||||
GSH_COMPILER_V = -v
|
||||
GSH_COMPILER_P = -p
|
||||
GSH_COMPILER_O = -o
|
||||
GSH_COMPILER_ALIGN = -align
|
||||
|
||||
clean:
|
||||
rm slang-convert main.o
|
||||
SLANG_DIR = slang-shaders
|
||||
|
||||
BLACKLIST :=
|
||||
BLACKLIST += $(SLANG_DIR)/dithering/shaders/bayer-matrix-dithering.slang
|
||||
BLACKLIST += $(SLANG_DIR)/scalefx/shaders/old/scalefx-pass3.slang
|
||||
BLACKLIST += $(SLANG_DIR)/scalefx/shaders/old/scalefx-pass7.slang
|
||||
BLACKLIST += $(SLANG_DIR)/scalefx/shaders/scalefx-pass1.slang
|
||||
BLACKLIST += $(SLANG_DIR)/scalefx/shaders/scalefx-pass2.slang
|
||||
BLACKLIST += $(SLANG_DIR)/scalefx/shaders/scalefx-pass4.slang
|
||||
BLACKLIST += $(SLANG_DIR)/scalefx/shaders/scalefx-pass4-hybrid.slang
|
||||
BLACKLIST += $(SLANG_DIR)/test/decode-format.slang
|
||||
BLACKLIST += $(SLANG_DIR)/test/format.slang
|
||||
BLACKLIST += $(wildcard $(SLANG_DIR)/crt/shaders/crt-royale/src/*.slang)
|
||||
BLACKLIST += $(SLANG_DIR)/slang-shaders/blurs/blur12x12shared.slang
|
||||
BLACKLIST += $(SLANG_DIR)/blurs/blur5x5-gamma-encode-every-fbo.slang
|
||||
BLACKLIST += $(SLANG_DIR)/blurs/blur12x12shared.slang
|
||||
BLACKLIST += $(SLANG_DIR)/ntsc/shaders/ntsc-xot.slang
|
||||
BLACKLIST += $(SLANG_DIR)/nedi/shaders/nedi-pass0.slang
|
||||
BLACKLIST += $(SLANG_DIR)/nedi/shaders/nedi-pass1.slang
|
||||
BLACKLIST += $(SLANG_DIR)/nedi/shaders/nedi-pass2.slang
|
||||
BLACKLIST += $(wildcard $(SLANG_DIR)/anti-aliasing/shaders/smaa/*.slang)
|
||||
|
||||
EXE_EXT :=
|
||||
|
||||
ifneq ($(findstring Linux,$(shell uname -a)),)
|
||||
else ifneq ($(findstring Darwin,$(shell uname -a)),)
|
||||
else
|
||||
EXE_EXT := .exe
|
||||
endif
|
||||
|
||||
SLANG_PARSER = ./slang-parse$(EXE_EXT)
|
||||
|
||||
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
|
||||
SLANG_SHADERS := $(call rwildcard,$(SLANG_DIR)/,*.slang)
|
||||
SLANG_SHADERS := $(filter-out $(BLACKLIST),$(SLANG_SHADERS))
|
||||
SLANG_SHADERS := $(SLANG_SHADERS:.slang=.gsh)
|
||||
|
||||
|
||||
|
||||
|
||||
all: $(SLANG_SHADERS)
|
||||
parser: $(SLANG_PARSER)
|
||||
|
||||
$(SLANG_PARSER): slang-parse.cpp
|
||||
$(CXX) $< -o $@ -g -O0 -Wall -I.
|
||||
|
||||
shaders: $(SLANG_SHADERS)
|
||||
|
||||
%.ppslang : %.slang
|
||||
$(GLSLC) -E $< -o $@
|
||||
|
||||
%.vert %.frag: %.ppslang $(SLANG_PARSER) grammar.txt
|
||||
$(SLANG_PARSER) --slang $< --vsh $*.vert --psh $*.frag
|
||||
|
||||
%.gsh: %.vert %.frag
|
||||
$(GSH_COMPILER) $(GSH_COMPILER_ALIGN) $(GSH_COMPILER_V) $*.vert $(GSH_COMPILER_P) $*.frag $(GSH_COMPILER_O) $@
|
||||
|
||||
.PRECIOUS: %.vert %.frag %.ppslang
|
||||
|
||||
clean-shaders:
|
||||
rm -rf $(SLANG_SHADERS)
|
||||
|
||||
clean-temp:
|
||||
rm -rf $(SLANG_SHADERS:.gsh=.ppslang)
|
||||
rm -rf $(SLANG_SHADERS:.gsh=.vert)
|
||||
rm -rf $(SLANG_SHADERS:.gsh=.frag)
|
||||
|
||||
clean-parser:
|
||||
rm -rf $(SLANG_PARSER) slang-parse.o
|
||||
|
||||
clean: clean-parser clean-shaders clean-temp
|
||||
|
@ -1,42 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
#### options ####
|
||||
|
||||
slang_dir=slang-shaders
|
||||
gshcompiler=$(pwd)/compiler.exe
|
||||
vshflag=--vsh
|
||||
pshflag=--psh
|
||||
outputflag=--out
|
||||
alignflag=--align
|
||||
|
||||
#################
|
||||
|
||||
|
||||
currentdir=$(pwd)
|
||||
|
||||
die ()
|
||||
{
|
||||
echo error while converting $name
|
||||
#mv -f tmp.vsh $currentdir
|
||||
#mv -f tmp.psh $currentdir
|
||||
#cp $1 $currentdir 2> /dev/null
|
||||
#exit 1
|
||||
}
|
||||
|
||||
|
||||
make
|
||||
|
||||
cd $slang_dir
|
||||
slang_dir=$(pwd)
|
||||
slang_files=`find $slang_dir -name "*.slang"`
|
||||
|
||||
for name in $slang_files ; do
|
||||
echo $name
|
||||
echo cd $(dirname $name)
|
||||
cd $(dirname $name)
|
||||
echo $currentdir/slang-convert --slang $name --vsh tmp.vsh --psh tmp.psh
|
||||
$currentdir/slang-convert --slang $(basename $name) --vsh tmp.vsh --psh tmp.psh
|
||||
echo $gshcompiler $alignflag $vshflag tmp.vsh $pshflag tmp.psh $outputflag `echo "$name" | sed "s/\.slang//"`.gsh
|
||||
$gshcompiler $alignflag $vshflag tmp.vsh $pshflag tmp.psh $outputflag `echo "$name" | sed "s/\.slang//"`.gsh || die $name
|
||||
rm -rf tmp.vsh tmp.psh
|
||||
done
|
55
wiiu/slang/grammar.txt
Normal file
55
wiiu/slang/grammar.txt
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
Program <- Version? (LineMarker / GoogleIncludeExtensionEnable / UniformBlock / Declaration / ConstArray / Stage / Indent / IgnoredKeyword / Line)*
|
||||
|
||||
~LineMarker <- '#line' (!EndOfLine .)* EndOfLine
|
||||
~GoogleIncludeExtensionEnable <- '#extension GL_GOOGLE_include_directive' (!EndOfLine .)* EndOfLine
|
||||
Line <- <(!EndOfLine !EndOfFile .)*> (EndOfLine / EndOfFile)
|
||||
~IgnoredKeyword <- !'const int' ('inline' / 'static ' / 'const ')
|
||||
Version <- '#'_'version' Space+ <Int> <(!EndOfLine .)*> EndOfLine
|
||||
Stage <- '#'_'pragma' Space+ 'stage' Space? <(!EndOfLine .)*> EndOfLine
|
||||
#.*Include <- '#'_'include' _ '"' <(!'"' .)*> '"' _ EndOfLine
|
||||
|
||||
|
||||
Declaration <- Layout? _ Qualifier Space _ Type Space _ Name _ ArraySize? _ EndOfStatement
|
||||
ConstArray <- Type Space _ Name _ ArraySize? _ '=' _ Array _ EndOfStatement
|
||||
UniformBlock <- Layout? _ 'uniform' _ StructName? _ '{' Member* '}' _ Name? _ EndOfStatement
|
||||
Member <- (_ Type Space _ Name _ ArraySize? _ EndOfStatement? _ Comment?)
|
||||
~Comment <- ('//' Line)
|
||||
|
||||
Value <- (Float / Int / (!EndOfStatement .)*)
|
||||
Array <- ('{' ( _ ArrayItem+ _ ',')* (_ ArrayItem+ _ )? '}')
|
||||
ArrayItem <- <(!'}'!',' (groupedItem/.))+>
|
||||
groupedItem <- '(' (!')' (groupedItem/.))+ ')'
|
||||
|
||||
Qualifier <- 'in' / 'out' / 'uniform'
|
||||
Type <- <'uint' / 'int' / 'ivec2' / 'ivec3' / 'ivec4' /
|
||||
'float' / 'vec2' / 'vec3' / 'vec4' /
|
||||
'bool' / 'bvec2' / 'bvec3' / 'bvec4' /
|
||||
'mat2x2' / 'mat2' /
|
||||
'mat3x2' / 'mat3x3' / 'mat3' /
|
||||
'mat4x2' / 'mat4x3' / 'mat4x4' / 'mat4' /
|
||||
'void' / 'sampler2D' / Name>
|
||||
StructName <- <Name>
|
||||
ArraySize <- '[' _ <Int> _ ']'
|
||||
Name <- ([a-z]/[A-Z]/'_'/[0-9])+
|
||||
Layout <- 'layout' _ '(' ( _ (Location / Binding / Set / PushConstant / Std) _ ','?)+ ')'
|
||||
Location <- 'location' _ '=' _ <Int>
|
||||
Binding <- 'binding' _ '=' _ <Int>
|
||||
Set <- 'set' _ '=' _ <Int>
|
||||
PushConstant <- 'push_constant'
|
||||
Std <- 'std' <Int>
|
||||
|
||||
|
||||
#.*Block <- '{' (Directive/ Statement / Block _)* '}'
|
||||
|
||||
|
||||
Float <- $< '-'? [0-9]+ '.' ([0-9]+ ('e-'[0-9]+)? )? 'f'? >
|
||||
Int <- < '-'? [0-9]+ >
|
||||
~EndOfStatement <- ';'
|
||||
~EndOfLine <- '\r\n' / '\n' / '\r'
|
||||
EndOfFile <- !.
|
||||
End <- EndOfLine / EndOfFile
|
||||
~_ <- [ \t\r\n]*
|
||||
Indent <- [ \t]
|
||||
~Space <- [ \t]
|
||||
|
@ -134,6 +134,8 @@ int main(int argc, const char** argv)
|
||||
fclose(vs_out_fp);
|
||||
fclose(ps_out_fp);
|
||||
|
||||
free(slang_buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
2775
wiiu/slang/peglib.h
Normal file
2775
wiiu/slang/peglib.h
Normal file
File diff suppressed because it is too large
Load Diff
271
wiiu/slang/slang-parse.cpp
Normal file
271
wiiu/slang/slang-parse.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <peglib.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
const char* slang_fn = NULL;
|
||||
const char* vs_asm_fn = NULL;
|
||||
const char* ps_asm_fn = NULL;
|
||||
const char* vs_out_fn = NULL;
|
||||
const char* ps_out_fn = NULL;
|
||||
bool verbose = false;
|
||||
|
||||
for(int i = 1; i < argc - 1; i++)
|
||||
{
|
||||
if(!strcmp(argv[i], "--slang"))
|
||||
slang_fn = argv[++i];
|
||||
else if(!strcmp(argv[i], "--vsource"))
|
||||
vs_asm_fn = argv[++i];
|
||||
else if(!strcmp(argv[i], "--psource"))
|
||||
ps_asm_fn = argv[++i];
|
||||
else if(!strcmp(argv[i], "--vsh"))
|
||||
vs_out_fn = argv[++i];
|
||||
else if(!strcmp(argv[i], "--psh"))
|
||||
ps_out_fn = argv[++i];
|
||||
else if(!strcmp(argv[i], "--verbose"))
|
||||
verbose = true;
|
||||
}
|
||||
|
||||
|
||||
if(!slang_fn || !vs_out_fn || !ps_out_fn || (!vs_asm_fn && ps_asm_fn) || (vs_asm_fn && !ps_asm_fn))
|
||||
{
|
||||
printf("Usage :\n");
|
||||
printf("%s --slang <slang input> --vsh <vsh output> --psh <psh output>\n", argv[0]);
|
||||
printf("%s --slang <slang input> --vsource <vsh asm input> --psource <psh asm input> --vsh <vsh output> --psh <psh output>\n", argv[0]);
|
||||
}
|
||||
|
||||
std::string slang;
|
||||
{
|
||||
std::ifstream fs(slang_fn);
|
||||
std::stringstream ss;
|
||||
ss << fs.rdbuf();
|
||||
slang = ss.str();
|
||||
}
|
||||
|
||||
std::string slang_grammar;
|
||||
{
|
||||
std::ifstream fs("grammar.txt");
|
||||
std::stringstream ss;
|
||||
ss << fs.rdbuf();
|
||||
slang_grammar = ss.str();
|
||||
}
|
||||
|
||||
peg::parser parser;
|
||||
parser.log = [&](size_t ln, size_t col, const std::string &msg) {
|
||||
std::cout << "Error parsing grammar:" << ln << ":" << col << ": " << msg << std::endl;
|
||||
};
|
||||
|
||||
if (!parser.load_grammar(slang_grammar.c_str())) {
|
||||
std::cout << "Failed to load grammar" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
parser.log = [&](size_t ln, size_t col, const std::string &msg) {
|
||||
std::cout << slang_fn << ":" << ln << ":" << col << ": " << msg << std::endl;
|
||||
};
|
||||
|
||||
parser.enable_ast();
|
||||
|
||||
std::shared_ptr<peg::Ast> ast;
|
||||
if (!parser.parse_n(slang.c_str(), slang.size(), ast)) {
|
||||
std::cout << "Error parsing slang file: " << slang_fn << std::endl;
|
||||
return 1;
|
||||
}
|
||||
ast = peg::AstOptimizer(false).optimize(ast);
|
||||
if(verbose)
|
||||
std::cout << peg::ast_to_s(ast) << std::flush;
|
||||
|
||||
if (ast->name != "Program") {
|
||||
std::cout << "Expected root node to be Program, not" << ast->name << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::stringstream common;
|
||||
std::stringstream vs;
|
||||
std::stringstream ps;
|
||||
|
||||
std::stringstream* out = &common;
|
||||
|
||||
common << "#version 150\n";
|
||||
common << "#define float2 vec2\n";
|
||||
common << "#define float3 vec3\n";
|
||||
common << "#define float4 vec4\n";
|
||||
for (std::shared_ptr<peg::Ast> &node : ast->nodes) {
|
||||
if (node->name == "Version") {
|
||||
/* do nothing */
|
||||
} else if (node->name == "UniformBlock") {
|
||||
int location = 0;
|
||||
int binding = 0;
|
||||
int set = 0;
|
||||
int std_val = 0;
|
||||
bool push_constant = false;
|
||||
std::string struct_name;
|
||||
std::string name;
|
||||
struct member_type
|
||||
{
|
||||
std::string type;
|
||||
std::string name;
|
||||
};
|
||||
std::vector<member_type> members;
|
||||
|
||||
for (std::shared_ptr<peg::Ast> &child : node->nodes) {
|
||||
if (child->name == "Layout") {
|
||||
for (std::shared_ptr<peg::Ast> &layout : child->nodes) {
|
||||
if (layout->name == "PushConstant") {
|
||||
push_constant = true;
|
||||
} else if (layout->name == "Location") {
|
||||
location = std::stoul(layout->token);
|
||||
} else if (layout->name == "Binding") {
|
||||
binding = std::stoul(layout->token);
|
||||
} else if (layout->name == "Set") {
|
||||
set = std::stoul(layout->token);
|
||||
} else if (layout->name == "Std") {
|
||||
std_val = std::stoul(layout->token);
|
||||
}
|
||||
}
|
||||
} else if (child->name == "StructName") {
|
||||
struct_name = child->token;
|
||||
} else if (child->name == "Name") {
|
||||
name = child->token;
|
||||
} else if (child->name == "Member") {
|
||||
member_type new_member;
|
||||
for (std::shared_ptr<peg::Ast> &member : child->nodes) {
|
||||
if (member->name == "Type") {
|
||||
new_member.type = member->token;
|
||||
} else if (member->name == "Name") {
|
||||
new_member.name = member->token;
|
||||
}
|
||||
}
|
||||
members.push_back(new_member);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
*out << "layout(location = " << (push_constant? "1" : "0");
|
||||
if(std_val)
|
||||
*out << ", std" << std_val;
|
||||
*out << ") ";
|
||||
#else
|
||||
if(std_val)
|
||||
*out << "layout(std" << std_val << ") ";
|
||||
#endif
|
||||
*out << "uniform " << struct_name << "\n{\n";
|
||||
for(member_type &member : members) {
|
||||
*out << " " << member.type << " " << member.name << ";\n";
|
||||
}
|
||||
*out << "}" << name << ";";
|
||||
|
||||
} else if (node->name == "Declaration") {
|
||||
int location = 0;
|
||||
int binding = 0;
|
||||
int set = 0;
|
||||
std::string qualifier;
|
||||
std::string type;
|
||||
std::string name;
|
||||
int array_size = 0;
|
||||
bool has_layout = false;
|
||||
|
||||
for (std::shared_ptr<peg::Ast> &child : node->nodes) {
|
||||
if (child->name == "Layout") {
|
||||
has_layout = true;
|
||||
for (std::shared_ptr<peg::Ast> &layout : child->nodes) {
|
||||
if (layout->name == "Location") {
|
||||
location = std::stoul(layout->token);
|
||||
} else if (layout->name == "Binding") {
|
||||
binding = std::stoul(layout->token);
|
||||
} else if (layout->name == "Set") {
|
||||
set = std::stoul(layout->token);
|
||||
}
|
||||
}
|
||||
} else if (child->name == "Qualifier") {
|
||||
qualifier = child->token;
|
||||
} else if (child->name == "Type") {
|
||||
type = child->token;
|
||||
} else if (child->name == "Name") {
|
||||
name = child->token;
|
||||
}else if (child->name == "ArraySize") {
|
||||
array_size = std::stoul(child->token);
|
||||
}
|
||||
}
|
||||
if(has_layout && type != "sampler2D")
|
||||
{
|
||||
*out << "layout(location = " << location << ") ";
|
||||
}
|
||||
|
||||
*out << qualifier << " " << type << " " << name;
|
||||
if(array_size)
|
||||
*out << "[" << array_size << "]";
|
||||
*out << ";";
|
||||
|
||||
} else if (node->name == "ConstArray") {
|
||||
std::string type;
|
||||
std::string name;
|
||||
int array_size = 0;
|
||||
std::vector<std::shared_ptr<peg::Ast>>* array;
|
||||
|
||||
for (std::shared_ptr<peg::Ast> &child : node->nodes) {
|
||||
if (child->name == "Type") {
|
||||
type = child->token;
|
||||
} else if (child->name == "Name") {
|
||||
name = child->token;
|
||||
} else if (child->name == "ArraySize") {
|
||||
array_size = std::stoul(child->token);
|
||||
} else if (child->name == "Array") {
|
||||
array = &child->nodes;
|
||||
}
|
||||
}
|
||||
*out << type << " " << name;
|
||||
if(array_size)
|
||||
*out << "[" << array_size << "]";
|
||||
*out << " = " << type;
|
||||
if(array_size)
|
||||
*out << "[" << array_size << "]";
|
||||
*out << "(";
|
||||
for (std::shared_ptr<peg::Ast> &item : *array) {
|
||||
if(array_size)
|
||||
*out << type << "(";
|
||||
*out << item->token;
|
||||
if(array_size)
|
||||
*out << ")";
|
||||
if(item != array->back())
|
||||
*out << ", ";
|
||||
}
|
||||
*out << ");";
|
||||
|
||||
} else if (node->name == "Stage") {
|
||||
std::string stage = node->token;
|
||||
std::transform(stage.begin(), stage.end(), stage.begin(), ::toupper);
|
||||
if(stage == "VERTEX")
|
||||
out = &vs;
|
||||
else
|
||||
out = &ps;
|
||||
} else if (node->name == "Indent"){
|
||||
*out << node->token;
|
||||
} else if (node->name == "Line"){
|
||||
*out << node->token << std::endl;
|
||||
} else {
|
||||
std::cout << "Unexcpected node " << node->name << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::ofstream fs(vs_out_fn);
|
||||
fs << common.str();
|
||||
fs << vs.str();
|
||||
}
|
||||
|
||||
{
|
||||
std::ofstream fs(ps_out_fn);
|
||||
fs << common.str();
|
||||
fs << ps.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user