Merge pull request #535 from Subv/gpu_swizzle
GPU: Support changing the texture swizzles for Maxwell textures.
This commit is contained in:
commit
37f50c8773
|
@ -681,6 +681,14 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, GLuint program,
|
||||||
Surface surface = res_cache.GetTextureSurface(texture);
|
Surface surface = res_cache.GetTextureSurface(texture);
|
||||||
if (surface != nullptr) {
|
if (surface != nullptr) {
|
||||||
state.texture_units[current_bindpoint].texture_2d = surface->texture.handle;
|
state.texture_units[current_bindpoint].texture_2d = surface->texture.handle;
|
||||||
|
state.texture_units[current_bindpoint].swizzle.r =
|
||||||
|
MaxwellToGL::SwizzleSource(texture.tic.x_source);
|
||||||
|
state.texture_units[current_bindpoint].swizzle.g =
|
||||||
|
MaxwellToGL::SwizzleSource(texture.tic.y_source);
|
||||||
|
state.texture_units[current_bindpoint].swizzle.b =
|
||||||
|
MaxwellToGL::SwizzleSource(texture.tic.z_source);
|
||||||
|
state.texture_units[current_bindpoint].swizzle.a =
|
||||||
|
MaxwellToGL::SwizzleSource(texture.tic.w_source);
|
||||||
} else {
|
} else {
|
||||||
// Can occur when texture addr is null or its memory is unmapped/invalid
|
// Can occur when texture addr is null or its memory is unmapped/invalid
|
||||||
state.texture_units[current_bindpoint].texture_2d = 0;
|
state.texture_units[current_bindpoint].texture_2d = 0;
|
||||||
|
|
|
@ -50,6 +50,10 @@ OpenGLState::OpenGLState() {
|
||||||
for (auto& texture_unit : texture_units) {
|
for (auto& texture_unit : texture_units) {
|
||||||
texture_unit.texture_2d = 0;
|
texture_unit.texture_2d = 0;
|
||||||
texture_unit.sampler = 0;
|
texture_unit.sampler = 0;
|
||||||
|
texture_unit.swizzle.r = GL_RED;
|
||||||
|
texture_unit.swizzle.g = GL_GREEN;
|
||||||
|
texture_unit.swizzle.b = GL_BLUE;
|
||||||
|
texture_unit.swizzle.a = GL_ALPHA;
|
||||||
}
|
}
|
||||||
|
|
||||||
lighting_lut.texture_buffer = 0;
|
lighting_lut.texture_buffer = 0;
|
||||||
|
@ -200,6 +204,15 @@ void OpenGLState::Apply() const {
|
||||||
if (texture_units[i].sampler != cur_state.texture_units[i].sampler) {
|
if (texture_units[i].sampler != cur_state.texture_units[i].sampler) {
|
||||||
glBindSampler(i, texture_units[i].sampler);
|
glBindSampler(i, texture_units[i].sampler);
|
||||||
}
|
}
|
||||||
|
// Update the texture swizzle
|
||||||
|
if (texture_units[i].swizzle.r != cur_state.texture_units[i].swizzle.r ||
|
||||||
|
texture_units[i].swizzle.g != cur_state.texture_units[i].swizzle.g ||
|
||||||
|
texture_units[i].swizzle.b != cur_state.texture_units[i].swizzle.b ||
|
||||||
|
texture_units[i].swizzle.a != cur_state.texture_units[i].swizzle.a) {
|
||||||
|
std::array<GLint, 4> mask = {texture_units[i].swizzle.r, texture_units[i].swizzle.g,
|
||||||
|
texture_units[i].swizzle.b, texture_units[i].swizzle.a};
|
||||||
|
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask.data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constbuffers
|
// Constbuffers
|
||||||
|
|
|
@ -85,6 +85,12 @@ public:
|
||||||
struct {
|
struct {
|
||||||
GLuint texture_2d; // GL_TEXTURE_BINDING_2D
|
GLuint texture_2d; // GL_TEXTURE_BINDING_2D
|
||||||
GLuint sampler; // GL_SAMPLER_BINDING
|
GLuint sampler; // GL_SAMPLER_BINDING
|
||||||
|
struct {
|
||||||
|
GLint r; // GL_TEXTURE_SWIZZLE_R
|
||||||
|
GLint g; // GL_TEXTURE_SWIZZLE_G
|
||||||
|
GLint b; // GL_TEXTURE_SWIZZLE_B
|
||||||
|
GLint a; // GL_TEXTURE_SWIZZLE_A
|
||||||
|
} swizzle;
|
||||||
} texture_units[32];
|
} texture_units[32];
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -180,4 +180,25 @@ inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) {
|
||||||
|
switch (source) {
|
||||||
|
case Tegra::Texture::SwizzleSource::Zero:
|
||||||
|
return GL_ZERO;
|
||||||
|
case Tegra::Texture::SwizzleSource::R:
|
||||||
|
return GL_RED;
|
||||||
|
case Tegra::Texture::SwizzleSource::G:
|
||||||
|
return GL_GREEN;
|
||||||
|
case Tegra::Texture::SwizzleSource::B:
|
||||||
|
return GL_BLUE;
|
||||||
|
case Tegra::Texture::SwizzleSource::A:
|
||||||
|
return GL_ALPHA;
|
||||||
|
case Tegra::Texture::SwizzleSource::OneInt:
|
||||||
|
case Tegra::Texture::SwizzleSource::OneFloat:
|
||||||
|
return GL_ONE;
|
||||||
|
}
|
||||||
|
NGLOG_CRITICAL(Render_OpenGL, "Unimplemented swizzle source={}", static_cast<u32>(source));
|
||||||
|
UNREACHABLE();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace MaxwellToGL
|
} // namespace MaxwellToGL
|
||||||
|
|
|
@ -316,6 +316,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
|
||||||
}};
|
}};
|
||||||
|
|
||||||
state.texture_units[0].texture_2d = screen_info.display_texture;
|
state.texture_units[0].texture_2d = screen_info.display_texture;
|
||||||
|
state.texture_units[0].swizzle = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices.data());
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices.data());
|
||||||
|
|
|
@ -122,6 +122,17 @@ enum class ComponentType : u32 {
|
||||||
FLOAT = 7
|
FLOAT = 7
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SwizzleSource : u32 {
|
||||||
|
Zero = 0,
|
||||||
|
|
||||||
|
R = 2,
|
||||||
|
G = 3,
|
||||||
|
B = 4,
|
||||||
|
A = 5,
|
||||||
|
OneInt = 6,
|
||||||
|
OneFloat = 7,
|
||||||
|
};
|
||||||
|
|
||||||
union TextureHandle {
|
union TextureHandle {
|
||||||
u32 raw;
|
u32 raw;
|
||||||
BitField<0, 20, u32> tic_id;
|
BitField<0, 20, u32> tic_id;
|
||||||
|
@ -139,6 +150,11 @@ struct TICEntry {
|
||||||
BitField<10, 3, ComponentType> g_type;
|
BitField<10, 3, ComponentType> g_type;
|
||||||
BitField<13, 3, ComponentType> b_type;
|
BitField<13, 3, ComponentType> b_type;
|
||||||
BitField<16, 3, ComponentType> a_type;
|
BitField<16, 3, ComponentType> a_type;
|
||||||
|
|
||||||
|
BitField<19, 3, SwizzleSource> x_source;
|
||||||
|
BitField<22, 3, SwizzleSource> y_source;
|
||||||
|
BitField<25, 3, SwizzleSource> z_source;
|
||||||
|
BitField<28, 3, SwizzleSource> w_source;
|
||||||
};
|
};
|
||||||
u32 address_low;
|
u32 address_low;
|
||||||
union {
|
union {
|
||||||
|
|
Reference in New Issue