gsdx-ogl:

* implement shader code (subset that seem to be used in SW mode)
* some hack to fix some alignment issue with GSVertexPT1 structure
* Lots of various opengl fixes. Remaining unsupported GL feature are inside SDL.


git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@4974 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2011-11-30 21:42:41 +00:00
parent 133847e8a2
commit eb3eafa090
7 changed files with 261 additions and 190 deletions

View File

@ -658,6 +658,8 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
}
assert(0);
// GL_NV_copy_image seem like the good extension but not supported on AMD...
// FIXME attach the texture to the FBO
GSTextureOGL* st_ogl = (GSTextureOGL*) st;
GSTextureOGL* dt_ogl = (GSTextureOGL*) dt;
@ -692,9 +694,6 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
// probably no difficult to convert when all helpers function will be done
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL* ps_cb, GSBlendStateOGL* bs, bool linear)
{
//TODO later
assert(0);
#if 0
if(!st || !dt)
{
ASSERT(0);
@ -718,7 +717,8 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
float right = dr.z * 2 / ds.x - 1.0f;
float bottom = 1.0f - dr.w * 2 / ds.y;
GSVertexPT1 vertices[] =
//FIXME aligment issue
GSVertexPT1 vertices[] __attribute__ ((aligned (16))) =
{
{GSVector4(left, top, 0.5f, 1.0f), GSVector2(sr.x, sr.y)},
{GSVector4(right, top, 0.5f, 1.0f), GSVector2(sr.z, sr.y)},
@ -727,8 +727,8 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
};
IASetVertexBuffer(vertices, sizeof(vertices[0]), countof(vertices));
IASetInputLayout(m_convert.il);
IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
IASetInputLayout(m_convert.il, 2);
IASetPrimitiveTopology(GL_TRIANGLE_STRIP);
// vs
@ -736,12 +736,12 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
// gs
GSSetShader(NULL);
GSSetShader(0);
// ps
PSSetShaderResources(st, NULL);
PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, NULL);
PSSetSamplerState(linear ? m_convert.ln : m_convert.pt, 0);
PSSetShader(ps, ps_cb);
//
@ -753,7 +753,9 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
EndScene();
PSSetShaderResources(NULL, NULL);
#endif
// FIXME: disable it when code is working
CheckDebugLog();
}
void GSDeviceOGL::DoMerge(GSTexture* st[2], GSVector4* sr, GSTexture* dt, GSVector4* dr, bool slbg, bool mmod, const GSVector4& c)
@ -847,7 +849,7 @@ void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t stride, size_t
glGenBuffers(1, &m_vb);
// FIXME: GL_DYNAMIC_DRAW vs GL_STREAM_DRAW !!!
glBindBuffer(GL_ARRAY_BUFFER, m_vb);
glBufferData(GL_ARRAY_BUFFER, m_vertices.limit, NULL, GL_DYNAMIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, m_vertices.limit * stride, NULL, GL_DYNAMIC_DRAW);
}
// append data or go back to the beginning
@ -959,10 +961,12 @@ void GSDeviceOGL::PSSetShader(GLuint ps, GSUniformBufferOGL* ps_cb)
// glBindSampler(1 , sampler);
if (m_srv_changed || m_ss_changed) {
for (uint i=0 ; i < 3; i++) {
if (m_state.ps_srv[i] != NULL) {
m_state.ps_srv[i]->EnableUnit(i);
glBindSampler(i, m_state.ps_ss[i]);
}
}
}
#if 0
if (m_srv_changed)
{
@ -1021,6 +1025,8 @@ void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf)
m_state.bs = bs;
m_state.bf = bf;
if (bs->m_enable) {
glEnable(GL_BLEND);
// FIXME: double check when blend stuff is complete
if (bs->m_func_sRGB == GL_CONSTANT_COLOR || bs->m_func_sRGB == GL_ONE_MINUS_CONSTANT_COLOR
|| bs->m_func_dRGB == GL_CONSTANT_COLOR || bs->m_func_dRGB == GL_ONE_MINUS_CONSTANT_COLOR)
@ -1028,6 +1034,8 @@ void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf)
glBlendEquationSeparate(bs->m_equation_RGB, bs->m_equation_ALPHA);
glBlendFuncSeparate(bs->m_func_sRGB, bs->m_func_dRGB, bs->m_func_sALPHA, bs->m_func_dALPHA);
} else
glDisable(GL_BLEND);
}
}
@ -1087,7 +1095,11 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
{
m_state.scissor = r;
// FIXME check position
glScissor(r.x, r.w, r.z-r.x, r.y-r.w);
// x = 0,
// y = 0,
// z = 512,
// w = 512
glScissor(r.x, r.y, r.z-r.x, r.w-r.y);
#if 0
m_ctx->RSSetScissorRects(1, r);
#endif
@ -1096,21 +1108,35 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const std::string& entry, GLenum type, GLuint* program)
{
// Could be useful to filter ubber shader
// *****************************************************
// Build a header string
// *****************************************************
// First select the version (must be the first line so we need to generate it
std::string version = "#version 410\n#extension GL_ARB_shading_language_420pack: enable\n";
// Allow to puts several shader in 1 files
std::string shader_type;
switch (type) {
case GL_VERTEX_SHADER:
shader_type = "#define VERTEX_SHADER 1\n";
break;
case GL_GEOMETRY_SHADER:
shader_type = "#define GEOMETRY_SHADER 1\n";
break;
case GL_FRAGMENT_SHADER:
shader_type = "#define FRAGMENT_SHADER 1\n";
break;
default: assert(0);
}
// Select the entry point
// Select the entry point ie the main function
std::string entry_main = format("#define %s main\n", entry.c_str());
std::string header = version + shader_type + entry_main;
// *****************************************************
// Read the source file
// *****************************************************
std::string source;
std::string line;
// Each linux distributions have his rules for path so we give them the possibility to
@ -1135,16 +1161,34 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
fprintf(stderr, "Error opening %s: ", shader_file.c_str());
}
// Create a giant string with everythings
std::string full_source = shader_type + entry_main + source;
char* sources = (char*)malloc(full_source.size());
strncpy(sources, full_source.c_str(), full_source.size());
sources[full_source.size()] = '\0';
// Note it is better to separate header and source file to have the good line number
// in the glsl compiler report
const char** sources_array = (const char**)malloc(2*sizeof(char*));
char* source_str = (char*)malloc(source.size() + 1);
char* header_str = (char*)malloc(header.size() + 1);
sources_array[0] = header_str;
sources_array[1] = source_str;
*program = glCreateShaderProgramv(type, 1, (const char**)&sources);
source.copy(source_str, source.size(), 0);
source_str[source.size()] = '\0';
header.copy(header_str, header.size(), 0);
header_str[header.size()] = '\0';
free(sources);
*program = glCreateShaderProgramv(type, 2, sources_array);
free(source_str);
free(header_str);
free(sources_array);
// Print a nice debug log
GLint log_length = 0;
glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &log_length);
char* log = (char*)malloc(log_length);
glGetProgramInfoLog(*program, log_length, NULL, log);
fprintf(stderr, "%s", log);
free(log);
}
void GSDeviceOGL::CheckDebugLog()
@ -1199,6 +1243,9 @@ void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsi
strcpy(debSource, "Application");
else if(source == GL_DEBUG_SOURCE_OTHER_ARB)
strcpy(debSource, "Other");
else
strcpy(debSource, "UNKNOW");
if(type == GL_DEBUG_TYPE_ERROR_ARB)
strcpy(debType, "Error");
@ -1212,6 +1259,8 @@ void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsi
strcpy(debType, "Performance");
else if(type == GL_DEBUG_TYPE_OTHER_ARB)
strcpy(debType, "Other");
else
strcpy(debType, "UNKNOW");
if(severity == GL_DEBUG_SEVERITY_HIGH_ARB)
strcpy(debSev, "High");

View File

@ -86,7 +86,6 @@ struct GSUniformBufferOGL {
{}
~GSUniformBufferOGL() {
if (buffer)
glDeleteBuffers(1, &buffer);
}
};
@ -280,7 +279,7 @@ class GSDeviceOGL : public GSDevice
void PSSetShaderResources(GSTexture* sr0, GSTexture* sr1);
void PSSetShaderResource(int i, GSTexture* sr);
void PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2);
void PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2 = 0);
void PSSetShader(GLuint ps, GSUniformBufferOGL* ps_cb);
void OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref);

View File

@ -94,8 +94,12 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
case GSTexture::RenderTarget:
// FIXME what is the real use case of this texture
// Maybe a texture will be better
glGenRenderbuffers(1, &m_texture_id);
m_texture_target = GL_RENDERBUFFER;
// glGenRenderbuffers(1, &m_texture_id);
// m_texture_target = GL_RENDERBUFFER;
// Buffer can not be read by shader and must be blit before. I see no point to use a render buffer
// when you can directly render on the texture. It said it could be faster...
glGenTextures(1, &m_texture_id);
m_texture_target = GL_TEXTURE_2D;
break;
case GSTexture::DepthStencil:
glGenRenderbuffers(1, &m_texture_id);
@ -104,8 +108,8 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
case GSTexture::Texture:
glGenTextures(1, &m_texture_id);
// FIXME, do we need rectangle (or better to use 2D texture)
//m_texture_target = GL_TEXTURE_2D;
m_texture_target = GL_TEXTURE_RECTANGLE;
m_texture_target = GL_TEXTURE_2D;
//m_texture_target = GL_TEXTURE_RECTANGLE;
// == For texture, the Unit must be selected
break;
case GSTexture::Offscreen:
@ -132,18 +136,25 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
// Allocate the buffer
switch (m_type) {
case GSTexture::RenderTarget:
case GSTexture::DepthStencil:
glBindRenderbuffer(m_texture_target, m_texture_id);
glRenderbufferStorageMultisample(m_texture_target, msaa_level, m_format, m_size.y, m_size.x);
break;
case GSTexture::RenderTarget:
case GSTexture::Texture:
// FIXME
// Howto allocate the texture unit !!!
// In worst case the HW renderer seems to use 3 texture unit
// For the moment SW renderer only use 1 so don't bother
EnableUnit(0);
glTexStorage2D_glew17(m_texture_target, 0, m_format, m_size.y, m_size.x);
// FIXME glTexStorage2D does not work yet on my system (4.2) extension but glTexImage2D seems ok
// glTexStorage2D_glew17(m_texture_target, 1, m_format, m_size.y, m_size.x);
// fprintf(stderr, "texture storage %d, %d\n", w, h);
if (m_format == GL_RGBA8) {
glTexImage2D(m_texture_target, 0, m_format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
else
assert(0);
break;
case GSTexture::Offscreen:
assert(0);
@ -170,6 +181,7 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
// To update only a part of the texture you can use:
// glTexSubImage2D — specify a two-dimensional texture subimage
switch (m_type) {
case GSTexture::RenderTarget:
case GSTexture::Texture:
// glTexSubImage2D specifies a two-dimensional subtexture for the current texture unit, specified with glActiveTexture.
// If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target
@ -179,9 +191,13 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
// FIXME I'm not confident with GL_UNSIGNED_BYTE type
// FIXME add a state check
glBindTexture(m_texture_target, m_texture_id);
glTexSubImage2D(m_texture_target, 0, r.left, r.bottom, r.right-r.left, r.top-r.bottom, m_format, GL_UNSIGNED_BYTE, data);
//void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data);
// fprintf(stderr, "texture coord %d, %d, %d, %d\n", r.x, r.y, r.z, r.w);
if (m_format == GL_RGBA8)
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.z-r.x, r.w-r.y, GL_RGBA, GL_UNSIGNED_BYTE, data);
else
assert(0);
break;
case GSTexture::RenderTarget:
case GSTexture::DepthStencil:
case GSTexture::Offscreen:
assert(0);
@ -204,11 +220,11 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
void GSTextureOGL::EnableUnit(uint unit)
{
switch (m_type) {
case GSTexture::RenderTarget:
case GSTexture::DepthStencil:
case GSTexture::Offscreen:
assert(0);
break;
case GSTexture::RenderTarget:
case GSTexture::Texture:
// FIXME
// Howto allocate the texture unit !!!

View File

@ -50,6 +50,10 @@ struct GSVertexPT1
{
GSVector4 p;
GSVector2 t;
#ifdef _LINUX
//FIXME aligment issue
GSVector2 pad;
#endif
};
struct GSVertexPT2

View File

@ -1,142 +1,137 @@
#if 0
struct VS_INPUT
{
float4 p : POSITION;
float2 t : TEXCOORD0;
};
//#version 420 // Keep it for editor detection
struct VS_OUTPUT
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
};
#ifdef VERTEX_SHADER
Texture2D Texture;
SamplerState TextureSampler;
layout(location = 0) in vec4 POSITION;
layout(location = 1) in vec2 TEXCOORD0;
float4 sample_c(float2 uv)
// FIXME set the interpolation (don't know what dx do)
// flat means that there is no interpolation. The value given to the fragment shader is based on the provoking vertex conventions.
//
// noperspective means that there will be linear interpolation in window-space. This is usually not what you want, but it can have its uses.
//
// smooth, the default, means to do perspective-correct interpolation.
//
// The centroid qualifier only matters when multisampling. If this qualifier is not present, then the value is interpolated to the pixel's center, anywhere in the pixel, or to one of the pixel's samples. This sample may lie outside of the actual primitive being rendered, since a primitive can cover only part of a pixel's area. The centroid qualifier is used to prevent this; the interpolation point must fall within both the pixel's area and the primitive's area.
// FIXME gl_Position
smooth layout(location = 0) out vec4 POSITION_OUT;
smooth layout(location = 1) out vec2 TEXCOORD0_OUT;
void vs_main()
{
return Texture.Sample(TextureSampler, uv);
POSITION_OUT = POSITION;
TEXCOORD0_OUT = TEXCOORD0_OUT;
gl_Position = POSITION; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position
}
struct PS_INPUT
#endif
#ifdef FRAGMENT_SHADER
// NOTE: pixel can be clip with "discard"
layout(location = 0) in vec4 SV_Position;
layout(location = 1) in vec2 TEXCOORD0;
out vec4 SV_Target0;
layout(binding = 0) uniform sampler2D TextureSampler;
vec4 sample_c(vec2 uv)
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
};
struct PS_OUTPUT
{
float4 c : SV_Target0;
};
VS_OUTPUT vs_main(VS_INPUT input)
{
VS_OUTPUT output;
output.p = input.p;
output.t = input.t;
return output;
return texture(TextureSampler, uv);
}
PS_OUTPUT ps_main0(PS_INPUT input)
vec4 ps_crt(vec2 uv, uint i)
{
PS_OUTPUT output;
output.c = sample_c(input.t);
return output;
}
PS_OUTPUT ps_main7(PS_INPUT input)
{
PS_OUTPUT output;
float4 c = sample_c(input.t);
c.a = dot(c.rgb, float3(0.299, 0.587, 0.114));
output.c = c;
return output;
}
float4 ps_crt(PS_INPUT input, int i)
{
float4 mask[4] =
vec4 mask[4] =
{
float4(1, 0, 0, 0),
float4(0, 1, 0, 0),
float4(0, 0, 1, 0),
float4(1, 1, 1, 0)
vec4(1, 0, 0, 0),
vec4(0, 1, 0, 0),
vec4(0, 0, 1, 0),
vec4(1, 1, 1, 0)
};
return sample_c(input.t) * saturate(mask[i] + 0.5f);
return sample_c(uv) * clamp((mask[i] + 0.5f), 0.0f, 1.0f);
}
uint ps_main1(PS_INPUT input) : SV_Target0
void ps_main0()
{
float4 c = sample_c(input.t);
c.a *= 256.0f / 127; // hm, 0.5 won't give us 1.0 if we just multiply with 2
uint4 i = c * float4(0x001f, 0x03e0, 0x7c00, 0x8000);
return (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000);
SV_Target0 = sample_c(TEXCOORD0);
}
PS_OUTPUT ps_main2(PS_INPUT input)
void ps_main7()
{
PS_OUTPUT output;
vec4 c = sample_c(TEXCOORD0);
clip(sample_c(input.t).a - 128.0f / 255); // >= 0x80 pass
c.a = dot(c.rgb, vec3(0.299, 0.587, 0.114));
output.c = 0;
return output;
SV_Target0 = c;
}
PS_OUTPUT ps_main3(PS_INPUT input)
void ps_main5() // triangular
{
PS_OUTPUT output;
clip(127.95f / 255 - sample_c(input.t).a); // < 0x80 pass (== 0x80 should not pass)
output.c = 0;
return output;
}
PS_OUTPUT ps_main4(PS_INPUT input)
{
PS_OUTPUT output;
output.c = fmod(sample_c(input.t) * 255 + 0.5f, 256) / 255;
return output;
}
PS_OUTPUT ps_main5(PS_INPUT input) // triangular
{
PS_OUTPUT output;
uint4 p = (uint4)input.p;
//uint4 p = (uint4)input.p;
highp uvec4 p = uvec4(SV_Position);
// output.c = ps_crt(input, ((p.x + (p.y & 1) * 3) >> 1) % 3);
output.c = ps_crt(input, ((p.x + ((p.y >> 1) & 1) * 3) >> 1) % 3);
vec4 c = ps_crt(TEXCOORD0, ((p.x + ((p.y >> 1) & 1) * 3) >> 1) % 3);
return output;
SV_Target0 = c;
}
PS_OUTPUT ps_main6(PS_INPUT input) // diagonal
void ps_main6() // diagonal
{
PS_OUTPUT output;
uvec4 p = uvec4(SV_Position);
uint4 p = (uint4)input.p;
vec4 c = ps_crt(TEXCOORD0, (p.x + (p.y % 3)) % 3);
output.c = ps_crt(input, (p.x + (p.y % 3)) % 3);
return output;
SV_Target0 = c;
}
// Texture2D Texture;
// SamplerState TextureSampler;
//
// uint ps_main1(PS_INPUT input) : SV_Target0
// {
// float4 c = sample_c(input.t);
//
// c.a *= 256.0f / 127; // hm, 0.5 won't give us 1.0 if we just multiply with 2
//
// uint4 i = c * float4(0x001f, 0x03e0, 0x7c00, 0x8000);
//
// return (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000);
// }
//
// PS_OUTPUT ps_main2(PS_INPUT input)
// {
// PS_OUTPUT output;
//
// clip(sample_c(input.t).a - 128.0f / 255); // >= 0x80 pass
//
// output.c = 0;
//
// return output;
// }
//
// PS_OUTPUT ps_main3(PS_INPUT input)
// {
// PS_OUTPUT output;
//
// clip(127.95f / 255 - sample_c(input.t).a); // < 0x80 pass (== 0x80 should not pass)
//
// output.c = 0;
//
// return output;
// }
//
// PS_OUTPUT ps_main4(PS_INPUT input)
// {
// PS_OUTPUT output;
//
// output.c = fmod(sample_c(input.t) * 255 + 0.5f, 256) / 255;
//
// return output;
// }
//
#endif

View File

@ -1,46 +1,54 @@
#if 0
//#version 420 // Keep it for editor detection
Texture2D Texture;
SamplerState Sampler;
#ifdef FRAGMENT_SHADER
layout(location = 0) in vec4 SV_Position;
layout(location = 1) in vec2 TEXCOORD0;
cbuffer cb0
out vec4 SV_Target0;
layout(std140, binding = 1) uniform cb0
{
float2 ZrH;
vec2 ZrH;
float hH;
};
struct PS_INPUT
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
};
layout(binding = 0) uniform sampler2D TextureSampler;
float4 ps_main0(PS_INPUT input) : SV_Target0
// TODO ensure that clip (discard) is < 0 and not <= 0 ???
void ps_main0()
{
clip(frac(input.t.y * hH) - 0.5);
// I'm not sure it impact us but be safe to lookup texture before conditional if
// see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control
vec4 c = texture(TextureSampler, TEXCOORD0);
if (fract(TEXCOORD0.y * hH) - 0.5 < 0.0)
discard;
return Texture.Sample(Sampler, input.t);
SV_Target0 = c;
}
float4 ps_main1(PS_INPUT input) : SV_Target0
void ps_main1()
{
clip(0.5 - frac(input.t.y * hH));
// I'm not sure it impact us but be safe to lookup texture before conditional if
// see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control
vec4 c = texture(TextureSampler, TEXCOORD0);
if (0.5 - fract(TEXCOORD0.y * hH) < 0.0)
discard;
return Texture.Sample(Sampler, input.t);
SV_Target0 = c;
}
float4 ps_main2(PS_INPUT input) : SV_Target0
void ps_main2()
{
float4 c0 = Texture.Sample(Sampler, input.t - ZrH);
float4 c1 = Texture.Sample(Sampler, input.t);
float4 c2 = Texture.Sample(Sampler, input.t + ZrH);
vec4 c0 = texture(TextureSampler, TEXCOORD0 - ZrH);
vec4 c1 = texture(TextureSampler, TEXCOORD0);
vec4 c2 = texture(TextureSampler, TEXCOORD0 + ZrH);
return (c0 + c1 * 2 + c2) / 4;
SV_Target0 = (c0 + c1 * 2 + c2) / 4;
}
float4 ps_main3(PS_INPUT input) : SV_Target0
void ps_main3()
{
return Texture.Sample(Sampler, input.t);
SV_Target0 = texture(TextureSampler, TEXCOORD0);
}
#endif

View File

@ -1,31 +1,31 @@
#if 0
//#version 420 // Keep it for editor detection
Texture2D Texture;
SamplerState Sampler;
#ifdef FRAGMENT_SHADER
cbuffer cb0
layout(location = 0) in vec4 SV_Position;
layout(location = 1) in vec2 TEXCOORD0;
out vec4 SV_Target0;
layout(std140, binding = 1) uniform cb0
{
float4 BGColor;
vec4 BGColor;
};
struct PS_INPUT
{
float4 p : SV_Position;
float2 t : TEXCOORD0;
};
layout(binding = 0) uniform sampler2D TextureSampler;
float4 ps_main0(PS_INPUT input) : SV_Target0
void ps_main0()
{
float4 c = Texture.Sample(Sampler, input.t);
vec4 c = texture(TextureSampler, TEXCOORD0);
c.a = min(c.a * 2, 1);
return c;
SV_Target0 = c;
}
float4 ps_main1(PS_INPUT input) : SV_Target0
void ps_main1()
{
float4 c = Texture.Sample(Sampler, input.t);
vec4 c = texture(TextureSampler, TEXCOORD0);
c.a = BGColor.a;
return c;
SV_Target0 = c;
}
#endif