VideoCore: Keep track of the active texture.

This commit is contained in:
Emmanuel Gil Peyrot 2016-03-11 00:54:39 +01:00
parent 62b105b695
commit 624c767a1e
5 changed files with 36 additions and 17 deletions

View file

@ -123,7 +123,7 @@ void RasterizerOpenGL::InitObjects() {
state.draw.framebuffer = framebuffer.handle; state.draw.framebuffer = framebuffer.handle;
state.Apply(); state.Apply();
glActiveTexture(GL_TEXTURE0); state.SetActiveTexture(GL_TEXTURE0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_color_texture.texture.handle, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_color_texture.texture.handle, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fb_depth_texture.texture.handle, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fb_depth_texture.texture.handle, 0);
@ -131,7 +131,7 @@ void RasterizerOpenGL::InitObjects() {
lighting_lut[i].Create(); lighting_lut[i].Create();
state.lighting_lut[i].texture_1d = lighting_lut[i].handle; state.lighting_lut[i].texture_1d = lighting_lut[i].handle;
glActiveTexture(GL_TEXTURE3 + i); state.SetActiveTexture(GL_TEXTURE3 + i);
glBindTexture(GL_TEXTURE_1D, state.lighting_lut[i].texture_1d); glBindTexture(GL_TEXTURE_1D, state.lighting_lut[i].texture_1d);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, 256, 0, GL_RGBA, GL_FLOAT, nullptr); glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, 256, 0, GL_RGBA, GL_FLOAT, nullptr);
@ -621,7 +621,7 @@ void RasterizerOpenGL::ReconfigureColorTexture(TextureInfo& texture, Pica::Regs:
state.texture_units[0].texture_2d = texture.texture.handle; state.texture_units[0].texture_2d = texture.texture.handle;
state.Apply(); state.Apply();
glActiveTexture(GL_TEXTURE0); state.SetActiveTexture(GL_TEXTURE0);
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0,
texture.gl_format, texture.gl_type, nullptr); texture.gl_format, texture.gl_type, nullptr);
@ -664,7 +664,7 @@ void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::
state.texture_units[0].texture_2d = texture.texture.handle; state.texture_units[0].texture_2d = texture.texture.handle;
state.Apply(); state.Apply();
glActiveTexture(GL_TEXTURE0); state.SetActiveTexture(GL_TEXTURE0);
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0,
texture.gl_format, texture.gl_type, nullptr); texture.gl_format, texture.gl_type, nullptr);
@ -934,7 +934,7 @@ void RasterizerOpenGL::SyncLightingLUT(unsigned lut_index) {
if (new_data != lighting_lut_data[lut_index]) { if (new_data != lighting_lut_data[lut_index]) {
lighting_lut_data[lut_index] = new_data; lighting_lut_data[lut_index] = new_data;
glActiveTexture(GL_TEXTURE3 + lut_index); state.SetActiveTexture(GL_TEXTURE3 + lut_index);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 256, GL_RGBA, GL_FLOAT, lighting_lut_data[lut_index].data()); glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 256, GL_RGBA, GL_FLOAT, lighting_lut_data[lut_index].data());
} }
} }
@ -1043,7 +1043,7 @@ void RasterizerOpenGL::ReloadColorBuffer() {
state.texture_units[0].texture_2d = fb_color_texture.texture.handle; state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
state.Apply(); state.Apply();
glActiveTexture(GL_TEXTURE0); state.SetActiveTexture(GL_TEXTURE0);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fb_color_texture.width, fb_color_texture.height, glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fb_color_texture.width, fb_color_texture.height,
fb_color_texture.gl_format, fb_color_texture.gl_type, temp_fb_color_buffer.get()); fb_color_texture.gl_format, fb_color_texture.gl_type, temp_fb_color_buffer.get());
@ -1100,7 +1100,7 @@ void RasterizerOpenGL::ReloadDepthBuffer() {
state.texture_units[0].texture_2d = fb_depth_texture.texture.handle; state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
state.Apply(); state.Apply();
glActiveTexture(GL_TEXTURE0); state.SetActiveTexture(GL_TEXTURE0);
if (fb_depth_texture.format == Pica::Regs::DepthFormat::D24S8) { if (fb_depth_texture.format == Pica::Regs::DepthFormat::D24S8) {
// TODO(Subv): There is a bug with Intel Windows drivers that makes glTexSubImage2D not change the stencil buffer. // TODO(Subv): There is a bug with Intel Windows drivers that makes glTexSubImage2D not change the stencil buffer.
// The bug has been reported to Intel (https://communities.intel.com/message/324464) // The bug has been reported to Intel (https://communities.intel.com/message/324464)
@ -1133,7 +1133,7 @@ void RasterizerOpenGL::CommitColorBuffer() {
state.texture_units[0].texture_2d = fb_color_texture.texture.handle; state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
state.Apply(); state.Apply();
glActiveTexture(GL_TEXTURE0); state.SetActiveTexture(GL_TEXTURE0);
glGetTexImage(GL_TEXTURE_2D, 0, fb_color_texture.gl_format, fb_color_texture.gl_type, temp_gl_color_buffer.get()); glGetTexImage(GL_TEXTURE_2D, 0, fb_color_texture.gl_format, fb_color_texture.gl_type, temp_gl_color_buffer.get());
state.texture_units[0].texture_2d = 0; state.texture_units[0].texture_2d = 0;
@ -1173,7 +1173,7 @@ void RasterizerOpenGL::CommitDepthBuffer() {
state.texture_units[0].texture_2d = fb_depth_texture.texture.handle; state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
state.Apply(); state.Apply();
glActiveTexture(GL_TEXTURE0); state.SetActiveTexture(GL_TEXTURE0);
glGetTexImage(GL_TEXTURE_2D, 0, fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_gl_depth_buffer.get()); glGetTexImage(GL_TEXTURE_2D, 0, fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_gl_depth_buffer.get());
state.texture_units[0].texture_2d = 0; state.texture_units[0].texture_2d = 0;

View file

@ -34,7 +34,7 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text
new_texture->texture.Create(); new_texture->texture.Create();
state.texture_units[texture_unit].texture_2d = new_texture->texture.handle; state.texture_units[texture_unit].texture_2d = new_texture->texture.handle;
state.Apply(); state.Apply();
glActiveTexture(GL_TEXTURE0 + texture_unit); state.SetActiveTexture(GL_TEXTURE0 + texture_unit);
u8* texture_src_data = Memory::GetPhysicalPointer(info.physical_address); u8* texture_src_data = Memory::GetPhysicalPointer(info.physical_address);

View file

@ -163,10 +163,15 @@ void OpenGLState::Apply() {
glLogicOp(logic_op); glLogicOp(logic_op);
} }
GLenum last_texture = active_texture;
// Textures // Textures
for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) { for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) {
if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) { if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) {
glActiveTexture(GL_TEXTURE0 + i); if (last_texture != GL_TEXTURE0 + i) {
glActiveTexture(GL_TEXTURE0 + i);
last_texture = GL_TEXTURE0 + i;
}
glBindTexture(GL_TEXTURE_2D, texture_units[i].texture_2d); glBindTexture(GL_TEXTURE_2D, texture_units[i].texture_2d);
} }
if (texture_units[i].sampler != cur_state.texture_units[i].sampler) { if (texture_units[i].sampler != cur_state.texture_units[i].sampler) {
@ -177,11 +182,17 @@ void OpenGLState::Apply() {
// Lighting LUTs // Lighting LUTs
for (unsigned i = 0; i < ARRAY_SIZE(lighting_lut); ++i) { for (unsigned i = 0; i < ARRAY_SIZE(lighting_lut); ++i) {
if (lighting_lut[i].texture_1d != cur_state.lighting_lut[i].texture_1d) { if (lighting_lut[i].texture_1d != cur_state.lighting_lut[i].texture_1d) {
glActiveTexture(GL_TEXTURE3 + i); if (last_texture != GL_TEXTURE3 + i) {
glActiveTexture(GL_TEXTURE3 + i);
last_texture = GL_TEXTURE3 + i;
}
glBindTexture(GL_TEXTURE_1D, lighting_lut[i].texture_1d); glBindTexture(GL_TEXTURE_1D, lighting_lut[i].texture_1d);
} }
} }
if (last_texture != active_texture)
glActiveTexture(active_texture);
// Framebuffer // Framebuffer
if (draw.framebuffer != cur_state.draw.framebuffer) { if (draw.framebuffer != cur_state.draw.framebuffer) {
glBindFramebuffer(GL_FRAMEBUFFER, draw.framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, draw.framebuffer);

View file

@ -54,6 +54,14 @@ public:
} blend; } blend;
GLenum logic_op; // GL_LOGIC_OP_MODE GLenum logic_op; // GL_LOGIC_OP_MODE
GLenum active_texture = GL_TEXTURE0; // GL_ACTIVE_TEXTURE
void SetActiveTexture(GLenum unit) {
if (unit != active_texture) {
glActiveTexture(unit);
active_texture = unit;
}
}
// 3 texture units - one for each that is used in PICA fragment shader emulation // 3 texture units - one for each that is used in PICA fragment shader emulation
struct { struct {

View file

@ -192,7 +192,7 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
state.texture_units[0].texture_2d = texture.handle; state.texture_units[0].texture_2d = texture.handle;
state.Apply(); state.Apply();
glActiveTexture(GL_TEXTURE0); state.SetActiveTexture(GL_TEXTURE0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pixel_stride); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pixel_stride);
// Update existing texture // Update existing texture
@ -219,7 +219,7 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color
state.texture_units[0].texture_2d = texture.handle; state.texture_units[0].texture_2d = texture.handle;
state.Apply(); state.Apply();
glActiveTexture(GL_TEXTURE0); state.SetActiveTexture(GL_TEXTURE0);
u8 framebuffer_data[3] = { color_r, color_g, color_b }; u8 framebuffer_data[3] = { color_r, color_g, color_b };
// Update existing texture // Update existing texture
@ -267,7 +267,7 @@ void RendererOpenGL::InitOpenGLObjects() {
state.texture_units[0].texture_2d = texture.handle; state.texture_units[0].texture_2d = texture.handle;
state.Apply(); state.Apply();
glActiveTexture(GL_TEXTURE0); state.SetActiveTexture(GL_TEXTURE0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@ -330,7 +330,7 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
state.texture_units[0].texture_2d = texture.handle; state.texture_units[0].texture_2d = texture.handle;
state.Apply(); state.Apply();
glActiveTexture(GL_TEXTURE0); state.SetActiveTexture(GL_TEXTURE0);
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0,
texture.gl_format, texture.gl_type, nullptr); texture.gl_format, texture.gl_type, nullptr);
} }
@ -371,7 +371,7 @@ void RendererOpenGL::DrawScreens() {
glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data()); glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data());
// Bind texture in Texture Unit 0 // Bind texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0); state.SetActiveTexture(GL_TEXTURE0);
glUniform1i(uniform_color_texture, 0); glUniform1i(uniform_color_texture, 0);
DrawSingleScreenRotated(textures[0], (float)layout.top_screen.left, (float)layout.top_screen.top, DrawSingleScreenRotated(textures[0], (float)layout.top_screen.left, (float)layout.top_screen.top,