Merge pull request #492 from DrChat/gl_backend_changes
GL Backend Changes/Fixes
This commit is contained in:
commit
3b11de2c2d
|
@ -396,19 +396,24 @@ void GL4CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
// HACK: just use whatever our current framebuffer is.
|
// HACK: just use whatever our current framebuffer is.
|
||||||
GLuint framebuffer_texture = last_framebuffer_texture_;
|
GLuint framebuffer_texture = last_framebuffer_texture_;
|
||||||
/*GLuint framebuffer_texture = active_framebuffer_
|
|
||||||
? active_framebuffer_->color_targets[0]
|
if (last_framebuffer_texture_ == 0) {
|
||||||
: last_framebuffer_texture_;*/
|
framebuffer_texture =
|
||||||
|
active_framebuffer_ ? active_framebuffer_->color_targets[0] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy the the given framebuffer to the current backbuffer.
|
// Copy the the given framebuffer to the current backbuffer.
|
||||||
Rect2D src_rect(0, 0, frontbuffer_width ? frontbuffer_width : 1280,
|
Rect2D src_rect(0, 0, frontbuffer_width ? frontbuffer_width : 1280,
|
||||||
frontbuffer_height ? frontbuffer_height : 720);
|
frontbuffer_height ? frontbuffer_height : 720);
|
||||||
Rect2D dest_rect(0, 0, swap_state_.width, swap_state_.height);
|
Rect2D dest_rect(0, 0, swap_state_.width, swap_state_.height);
|
||||||
|
if (framebuffer_texture != 0) {
|
||||||
reinterpret_cast<xe::ui::gl::GLContext*>(context_.get())
|
reinterpret_cast<xe::ui::gl::GLContext*>(context_.get())
|
||||||
->blitter()
|
->blitter()
|
||||||
->CopyColorTexture2D(framebuffer_texture, src_rect,
|
->CopyColorTexture2D(
|
||||||
static_cast<GLuint>(swap_state_.back_buffer_texture),
|
framebuffer_texture, src_rect,
|
||||||
dest_rect, GL_LINEAR, true);
|
static_cast<GLuint>(swap_state_.back_buffer_texture), dest_rect,
|
||||||
|
GL_LINEAR, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (FLAGS_draw_all_framebuffers) {
|
if (FLAGS_draw_all_framebuffers) {
|
||||||
int32_t offsetx = (1280 - (1280 / 5));
|
int32_t offsetx = (1280 - (1280 / 5));
|
||||||
|
@ -465,6 +470,12 @@ void GL4CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||||
// TODO(benvanik): prevent this? fences?
|
// TODO(benvanik): prevent this? fences?
|
||||||
glFinish();
|
glFinish();
|
||||||
|
|
||||||
|
if (context_->WasLost()) {
|
||||||
|
// We've lost the context due to a TDR.
|
||||||
|
// TODO: Dump the current commands to a tracefile.
|
||||||
|
assert_always();
|
||||||
|
}
|
||||||
|
|
||||||
// Remove any dead textures, etc.
|
// Remove any dead textures, etc.
|
||||||
texture_cache_.Scavenge();
|
texture_cache_.Scavenge();
|
||||||
}
|
}
|
||||||
|
@ -581,8 +592,15 @@ bool GL4CommandProcessor::IssueDraw(PrimitiveType prim_type,
|
||||||
if (!draw_batcher_.CommitDraw()) {
|
if (!draw_batcher_.CommitDraw()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(benvanik): find a way to get around glVertexArrayVertexBuffer below.
|
// TODO(benvanik): find a way to get around glVertexArrayVertexBuffer below.
|
||||||
draw_batcher_.Flush(DrawBatcher::FlushMode::kMakeCoherent);
|
draw_batcher_.Flush(DrawBatcher::FlushMode::kMakeCoherent);
|
||||||
|
if (context_->WasLost()) {
|
||||||
|
// This draw lost us the context. This typically isn't hit.
|
||||||
|
assert_always();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,18 +135,24 @@ bool GL4Shader::CompileProgram() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get error log, if we failed to link.
|
// Output info log.
|
||||||
GLint link_status = 0;
|
|
||||||
glGetProgramiv(program_, GL_LINK_STATUS, &link_status);
|
|
||||||
if (!link_status) {
|
|
||||||
// log_length includes the null character.
|
// log_length includes the null character.
|
||||||
GLint log_length = 0;
|
GLint log_length = 0;
|
||||||
glGetProgramiv(program_, GL_INFO_LOG_LENGTH, &log_length);
|
glGetProgramiv(program_, GL_INFO_LOG_LENGTH, &log_length);
|
||||||
std::string info_log;
|
std::string info_log;
|
||||||
|
if (log_length > 0) {
|
||||||
info_log.resize(log_length - 1);
|
info_log.resize(log_length - 1);
|
||||||
glGetProgramInfoLog(program_, log_length, &log_length,
|
glGetProgramInfoLog(program_, log_length, &log_length, &info_log[0]);
|
||||||
const_cast<char*>(info_log.data()));
|
}
|
||||||
XELOGE("Unable to link program: %s", info_log.c_str());
|
|
||||||
|
if (!info_log.empty()) {
|
||||||
|
XELOGD("Shader log: %s", info_log.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get error log, if we failed to link.
|
||||||
|
GLint link_status = 0;
|
||||||
|
glGetProgramiv(program_, GL_LINK_STATUS, &link_status);
|
||||||
|
if (!link_status) {
|
||||||
host_error_log_ = std::move(info_log);
|
host_error_log_ = std::move(info_log);
|
||||||
assert_always("Unable to link generated shader");
|
assert_always("Unable to link generated shader");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -361,10 +361,10 @@ void GlslShaderTranslator::ProcessExecInstructionBegin(
|
||||||
EmitSourceDepth("{\n");
|
EmitSourceDepth("{\n");
|
||||||
break;
|
break;
|
||||||
case ParsedExecInstruction::Type::kConditional:
|
case ParsedExecInstruction::Type::kConditional:
|
||||||
EmitSourceDepth("if ((state.bool_consts[%d] & (1 << %d)) == %c) {\n",
|
EmitSourceDepth("if ((state.bool_consts[%d] & (1 << %d)) %c= 0) {\n",
|
||||||
instr.bool_constant_index / 32,
|
instr.bool_constant_index / 32,
|
||||||
instr.bool_constant_index % 32,
|
instr.bool_constant_index % 32,
|
||||||
instr.condition ? '1' : '0');
|
instr.condition ? '!' : '=');
|
||||||
break;
|
break;
|
||||||
case ParsedExecInstruction::Type::kPredicated:
|
case ParsedExecInstruction::Type::kPredicated:
|
||||||
EmitSourceDepth("if (%cp0) {\n", instr.condition ? ' ' : '!');
|
EmitSourceDepth("if (%cp0) {\n", instr.condition ? ' ' : '!');
|
||||||
|
@ -384,13 +384,13 @@ void GlslShaderTranslator::ProcessExecInstructionBegin(
|
||||||
|
|
||||||
void GlslShaderTranslator::ProcessExecInstructionEnd(
|
void GlslShaderTranslator::ProcessExecInstructionEnd(
|
||||||
const ParsedExecInstruction& instr) {
|
const ParsedExecInstruction& instr) {
|
||||||
Unindent();
|
|
||||||
EmitSourceDepth("}\n");
|
|
||||||
if (instr.is_end) {
|
if (instr.is_end) {
|
||||||
EmitSourceDepth("pc = 0xFFFF;\n");
|
EmitSourceDepth("pc = 0xFFFF;\n");
|
||||||
EmitSourceDepth("break;\n");
|
EmitSourceDepth("break;\n");
|
||||||
cf_wrote_pc_ = true;
|
cf_wrote_pc_ = true;
|
||||||
}
|
}
|
||||||
|
Unindent();
|
||||||
|
EmitSourceDepth("}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlslShaderTranslator::ProcessLoopStartInstruction(
|
void GlslShaderTranslator::ProcessLoopStartInstruction(
|
||||||
|
@ -494,10 +494,10 @@ void GlslShaderTranslator::ProcessJumpInstruction(
|
||||||
EmitSourceDepth("{\n");
|
EmitSourceDepth("{\n");
|
||||||
break;
|
break;
|
||||||
case ParsedJumpInstruction::Type::kConditional:
|
case ParsedJumpInstruction::Type::kConditional:
|
||||||
EmitSourceDepth("if ((state.bool_consts[%d] & (1 << %d)) == %c) {\n",
|
EmitSourceDepth("if ((state.bool_consts[%d] & (1 << %d)) %c= 0) {\n",
|
||||||
instr.bool_constant_index / 32,
|
instr.bool_constant_index / 32,
|
||||||
instr.bool_constant_index % 32,
|
instr.bool_constant_index % 32,
|
||||||
instr.condition ? '1' : '0');
|
instr.condition ? '!' : '=');
|
||||||
needs_fallthrough = true;
|
needs_fallthrough = true;
|
||||||
break;
|
break;
|
||||||
case ParsedJumpInstruction::Type::kPredicated:
|
case ParsedJumpInstruction::Type::kPredicated:
|
||||||
|
|
|
@ -156,6 +156,7 @@ void TracePlayer::PlayTraceOnThread(const uint8_t* trace_data,
|
||||||
pending_packet = nullptr;
|
pending_packet = nullptr;
|
||||||
}
|
}
|
||||||
if (pending_break) {
|
if (pending_break) {
|
||||||
|
playing_trace_ = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -202,6 +202,8 @@ struct SavedState {
|
||||||
|
|
||||||
void Blitter::Draw(GLuint src_texture, Rect2D src_rect, Rect2D dest_rect,
|
void Blitter::Draw(GLuint src_texture, Rect2D src_rect, Rect2D dest_rect,
|
||||||
GLenum filter) {
|
GLenum filter) {
|
||||||
|
assert_not_zero(src_texture);
|
||||||
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
glDisablei(GL_BLEND, 0);
|
glDisablei(GL_BLEND, 0);
|
||||||
|
|
|
@ -133,12 +133,20 @@ bool GLContext::Initialize(GLContext* share_context) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GLEW_ARB_robustness) {
|
||||||
|
robust_access_supported_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
int context_flags = 0;
|
int context_flags = 0;
|
||||||
if (FLAGS_gl_debug) {
|
if (FLAGS_gl_debug) {
|
||||||
context_flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
context_flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
||||||
}
|
}
|
||||||
|
if (robust_access_supported_) {
|
||||||
|
context_flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
||||||
|
}
|
||||||
|
|
||||||
int attrib_list[] = {WGL_CONTEXT_MAJOR_VERSION_ARB,
|
int attrib_list[] = {
|
||||||
|
WGL_CONTEXT_MAJOR_VERSION_ARB,
|
||||||
4,
|
4,
|
||||||
WGL_CONTEXT_MINOR_VERSION_ARB,
|
WGL_CONTEXT_MINOR_VERSION_ARB,
|
||||||
5,
|
5,
|
||||||
|
@ -146,6 +154,8 @@ bool GLContext::Initialize(GLContext* share_context) {
|
||||||
context_flags,
|
context_flags,
|
||||||
WGL_CONTEXT_PROFILE_MASK_ARB,
|
WGL_CONTEXT_PROFILE_MASK_ARB,
|
||||||
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
||||||
|
WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
|
robust_access_supported_ ? WGL_LOSE_CONTEXT_ON_RESET_ARB : 0,
|
||||||
0};
|
0};
|
||||||
|
|
||||||
glrc_ = wglCreateContextAttribsARB(
|
glrc_ = wglCreateContextAttribsARB(
|
||||||
|
@ -201,7 +211,13 @@ std::unique_ptr<GLContext> GLContext::CreateOffscreen(
|
||||||
context_flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
context_flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
||||||
}
|
}
|
||||||
|
|
||||||
int attrib_list[] = {WGL_CONTEXT_MAJOR_VERSION_ARB,
|
bool robust_access_supported = parent_context->robust_access_supported_;
|
||||||
|
if (robust_access_supported) {
|
||||||
|
context_flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
||||||
|
}
|
||||||
|
|
||||||
|
int attrib_list[] = {
|
||||||
|
WGL_CONTEXT_MAJOR_VERSION_ARB,
|
||||||
4,
|
4,
|
||||||
WGL_CONTEXT_MINOR_VERSION_ARB,
|
WGL_CONTEXT_MINOR_VERSION_ARB,
|
||||||
5,
|
5,
|
||||||
|
@ -209,6 +225,8 @@ std::unique_ptr<GLContext> GLContext::CreateOffscreen(
|
||||||
context_flags,
|
context_flags,
|
||||||
WGL_CONTEXT_PROFILE_MASK_ARB,
|
WGL_CONTEXT_PROFILE_MASK_ARB,
|
||||||
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
||||||
|
WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
|
robust_access_supported ? WGL_LOSE_CONTEXT_ON_RESET_ARB : 0,
|
||||||
0};
|
0};
|
||||||
new_glrc = wglCreateContextAttribsARB(parent_context->dc_,
|
new_glrc = wglCreateContextAttribsARB(parent_context->dc_,
|
||||||
parent_context->glrc_, attrib_list);
|
parent_context->glrc_, attrib_list);
|
||||||
|
@ -223,6 +241,8 @@ std::unique_ptr<GLContext> GLContext::CreateOffscreen(
|
||||||
new_context->glrc_ = new_glrc;
|
new_context->glrc_ = new_glrc;
|
||||||
new_context->dc_ =
|
new_context->dc_ =
|
||||||
GetDC(HWND(parent_context->target_window_->native_handle()));
|
GetDC(HWND(parent_context->target_window_->native_handle()));
|
||||||
|
new_context->robust_access_supported_ =
|
||||||
|
parent_context->robust_access_supported_;
|
||||||
if (!new_context->MakeCurrent()) {
|
if (!new_context->MakeCurrent()) {
|
||||||
FatalGLError("Could not make new GL context current.");
|
FatalGLError("Could not make new GL context current.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -281,6 +301,8 @@ void GLContext::AssertExtensionsPresent() {
|
||||||
"OpenGL extension ARB_fragment_coord_conventions is required.");
|
"OpenGL extension ARB_fragment_coord_conventions is required.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClearCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLContext::DebugMessage(GLenum source, GLenum type, GLuint id,
|
void GLContext::DebugMessage(GLenum source, GLenum type, GLuint id,
|
||||||
|
@ -448,6 +470,28 @@ void GLContext::ClearCurrent() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GLContext::WasLost() {
|
||||||
|
if (!robust_access_supported_) {
|
||||||
|
// Can't determine if we lost the context.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context_lost_) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto status = glGetGraphicsResetStatusARB();
|
||||||
|
if (status != GL_NO_ERROR) {
|
||||||
|
// Graphics card reset.
|
||||||
|
XELOGE("============= TDR detected on context %p! Context %s =============",
|
||||||
|
glrc_, status == GL_GUILTY_CONTEXT_RESET ? "guilty" : "innocent");
|
||||||
|
context_lost_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void GLContext::BeginSwap() {
|
void GLContext::BeginSwap() {
|
||||||
SCOPE_profile_cpu_i("gpu", "xe::ui::gl::GLContext::BeginSwap");
|
SCOPE_profile_cpu_i("gpu", "xe::ui::gl::GLContext::BeginSwap");
|
||||||
float clear_color[] = {238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 1.0f};
|
float clear_color[] = {238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 1.0f};
|
||||||
|
|
|
@ -40,6 +40,7 @@ class GLContext : public GraphicsContext {
|
||||||
bool is_current() override;
|
bool is_current() override;
|
||||||
bool MakeCurrent() override;
|
bool MakeCurrent() override;
|
||||||
void ClearCurrent() override;
|
void ClearCurrent() override;
|
||||||
|
bool WasLost() override;
|
||||||
|
|
||||||
void BeginSwap() override;
|
void BeginSwap() override;
|
||||||
void EndSwap() override;
|
void EndSwap() override;
|
||||||
|
@ -80,6 +81,9 @@ class GLContext : public GraphicsContext {
|
||||||
|
|
||||||
Blitter blitter_;
|
Blitter blitter_;
|
||||||
std::unique_ptr<GLImmediateDrawer> immediate_drawer_;
|
std::unique_ptr<GLImmediateDrawer> immediate_drawer_;
|
||||||
|
|
||||||
|
bool context_lost_ = false;
|
||||||
|
bool robust_access_supported_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gl
|
} // namespace gl
|
||||||
|
|
|
@ -45,6 +45,12 @@ class GraphicsContext {
|
||||||
virtual bool MakeCurrent() = 0;
|
virtual bool MakeCurrent() = 0;
|
||||||
virtual void ClearCurrent() = 0;
|
virtual void ClearCurrent() = 0;
|
||||||
|
|
||||||
|
// Returns true if the OS took away our context because we caused a TDR or
|
||||||
|
// some other outstanding error. When this happens, this context, as well as
|
||||||
|
// any other shared contexts are junk.
|
||||||
|
// This context must be made current in order for this call to work properly.
|
||||||
|
virtual bool WasLost() { return false; }
|
||||||
|
|
||||||
virtual void BeginSwap() = 0;
|
virtual void BeginSwap() = 0;
|
||||||
virtual void EndSwap() = 0;
|
virtual void EndSwap() = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue