Kind of fixing window coordinates.

This commit is contained in:
Ben Vanik 2015-03-06 13:42:56 -08:00
parent 05bdbbbe84
commit 9db38ac860
3 changed files with 46 additions and 12 deletions

View File

@ -466,6 +466,18 @@ void CommandProcessor::UpdateWritePointer(uint32_t value) {
void CommandProcessor::WriteRegister(uint32_t index, uint32_t value) {
RegisterFile* regs = register_file_;
assert_true(index < RegisterFile::kRegisterCount);
// The command buffers will have multiple scissor updates before each draw.
// Only the first one ever seems valid, and the following are 8192x8192.
// As we need the valid scissor to do the draw, ignore those weird ones here.
if (index == XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL ||
index == XE_GPU_REG_PA_SC_WINDOW_SCISSOR_BR) {
if (value == 0x20002000) {
// Ignored?
return;
}
}
regs->values[index].u32 = value;
// If this is a COHER register, set the dirty flag.
@ -571,6 +583,10 @@ void CommandProcessor::IssueSwap() {
swap_params.width = window_scissor_br & 0x7FFF - swap_params.x;
swap_params.height = (window_scissor_br >> 16) & 0x7FFF - swap_params.y;
// This is just so that we draw reasonable garbage when drawing garbage.
swap_params.width = std::min(swap_params.width, 2560u);
swap_params.height = std::min(swap_params.height, 2560u);
PrepareForWait();
swap_handler_(swap_params);
ReturnFromWait();
@ -1695,8 +1711,6 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateRenderTargets() {
// TODO(benvanik): can we do this all named?
// TODO(benvanik): do we want this on READ too?
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, cached_framebuffer->framebuffer);
glViewport(0, 0, 1280, 720);
}
return UpdateStatus::kMismatch;
@ -1751,6 +1765,7 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateViewportState() {
uint32_t pa_su_sc_mode_cntl = regs[XE_GPU_REG_PA_SU_SC_MODE_CNTL].u32;
// Window parameters.
// http://ftp.tku.edu.tw/NetBSD/NetBSD-current/xsrc/external/mit/xf86-video-ati/dist/src/r600_reg_auto_r6xx.h
// See r200UpdateWindow:
// https://github.com/freedreno/mesa/blob/master/src/mesa/drivers/dri/r200/r200_state.c
if ((pa_su_sc_mode_cntl >> 17) & 1) {
@ -1828,8 +1843,27 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateViewportState() {
// assert_true(clip_enabled);
bool dx_clip = ((clip_control >> 20) & 0x1) == 0x1;
// assert_true(dx_clip);
// glClipControl(GL_UPPER_LEFT, GL_ZERO_TO_ONE);
auto& state_regs = update_viewport_state_regs_;
bool dirty = false;
dirty |= SetShadowRegister(state_regs.pa_sc_window_scissor_tl,
XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL);
dirty |= SetShadowRegister(state_regs.pa_sc_window_scissor_br,
XE_GPU_REG_PA_SC_WINDOW_SCISSOR_BR);
if (!dirty) {
return UpdateStatus::kCompatible;
}
draw_batcher_.Flush(DrawBatcher::FlushMode::kStateChange);
// TODO(benvanik): better scissor rect?
glViewport(
0, 0, std::min(2560u, state_regs.pa_sc_window_scissor_br & 0x7FFF),
std::min(2560u, (state_regs.pa_sc_window_scissor_br >> 16) & 0x7FFF));
return UpdateStatus::kMismatch;
}
CommandProcessor::UpdateStatus CommandProcessor::UpdateRasterizerState() {

View File

@ -298,6 +298,9 @@ class CommandProcessor {
void Reset() { std::memset(this, 0, sizeof(*this)); }
} update_render_targets_regs_;
struct UpdateViewportStateRegisters {
uint32_t pa_sc_window_scissor_tl;
uint32_t pa_sc_window_scissor_br;
UpdateViewportStateRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }
} update_viewport_state_regs_;

View File

@ -209,17 +209,14 @@ bool GL4Shader::PrepareVertexShader(
//" pos.w = 0.0;\n"
//" }\n"
" // NDC transform.\n"
" pos.x = pos.x * state.viewport_scale.x + \n"
" state.viewport_offset.x;\n"
" pos.y = pos.y * state.viewport_scale.y + \n"
" state.viewport_offset.y;\n"
" pos.z = pos.z * state.viewport_scale.z + \n"
" state.viewport_offset.z;\n"
" pos.xyz = pos.xyz * state.viewport_scale.xyz + \n"
" state.viewport_offset.xyz;\n"
" // NDC->Window with viewport.\n"
" pos.xy = pos.xy * state.window_offset.zw + state.window_offset.xy;\n"
" pos.xy = pos.xy / (vec2(1280.0 - 1.0, -720.0 + 1.0) / 2.0) +\n"
" vec2(-1.0, 1.0);\n"
" // Window adjustment.\n"
" // Put back in to ndc for glViewport to then take it back out again.\n"
" // Note the 1px scaling adjustment to fully fill the window.\n"
" pos.xy = pos.xy / ((state.window_scissor.zw - 1.0) /\n"
" vec2(2.0, -2.0)) + vec2(-1.0, 1.0);\n"
" return pos;\n"
"}\n";
std::string source =