Tracking whether state changes are compatible for batching.
This commit is contained in:
parent
07a82200f9
commit
3e61cc95cd
|
@ -1362,41 +1362,42 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!UpdateShaders(draw_command)) {
|
#define CHECK_ISSUE_UPDATE_STATUS(status, mismatch, error_message) \
|
||||||
PLOGE("Unable to prepare draw shaders");
|
{ \
|
||||||
return false;
|
if (status == UpdateStatus::kError) { \
|
||||||
}
|
PLOGE(error_message); \
|
||||||
if (!UpdateRenderTargets(draw_command)) {
|
return false; \
|
||||||
PLOGE("Unable to setup render targets");
|
} else if (status == UpdateStatus::kMismatch) { \
|
||||||
return false;
|
mismatch = true; \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateStatus status;
|
||||||
|
bool mismatch = false;
|
||||||
|
status = UpdateShaders(draw_command);
|
||||||
|
CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to prepare draw shaders");
|
||||||
|
status = UpdateRenderTargets(draw_command);
|
||||||
|
CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup render targets");
|
||||||
if (!active_framebuffer_) {
|
if (!active_framebuffer_) {
|
||||||
// No framebuffer, so nothing we do will actually have an effect.
|
// No framebuffer, so nothing we do will actually have an effect.
|
||||||
// Treat it as a no-op.
|
// Treat it as a no-op.
|
||||||
XETRACECP("No-op draw (no framebuffer set)");
|
XETRACECP("No-op draw (no framebuffer set)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!UpdateState(draw_command)) {
|
|
||||||
PLOGE("Unable to setup render state");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!UpdateConstants(draw_command)) {
|
|
||||||
PLOGE("Unable to update shader constants");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PopulateIndexBuffer(draw_command)) {
|
status = UpdateState(draw_command);
|
||||||
PLOGE("Unable to setup index buffer");
|
CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup render state");
|
||||||
return false;
|
status = UpdateConstants(draw_command);
|
||||||
}
|
CHECK_ISSUE_UPDATE_STATUS(status, mismatch,
|
||||||
if (!PopulateVertexBuffers(draw_command)) {
|
"Unable to update shader constants");
|
||||||
PLOGE("Unable to setup vertex buffers");
|
status = PopulateSamplers(draw_command);
|
||||||
return false;
|
CHECK_ISSUE_UPDATE_STATUS(status, mismatch,
|
||||||
}
|
"Unable to prepare draw samplers");
|
||||||
if (!PopulateSamplers(draw_command)) {
|
|
||||||
PLOGE("Unable to prepare draw samplers");
|
status = PopulateIndexBuffer(draw_command);
|
||||||
return false;
|
CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup index buffer");
|
||||||
}
|
status = PopulateVertexBuffers(draw_command);
|
||||||
|
CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup vertex buffers");
|
||||||
|
|
||||||
GLenum prim_type = 0;
|
GLenum prim_type = 0;
|
||||||
switch (cmd.prim_type) {
|
switch (cmd.prim_type) {
|
||||||
|
@ -1481,7 +1482,8 @@ bool CommandProcessor::SetShadowRegister(float& dest, uint32_t register_name) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::UpdateRenderTargets(DrawCommand* draw_command) {
|
CommandProcessor::UpdateStatus CommandProcessor::UpdateRenderTargets(
|
||||||
|
DrawCommand* draw_command) {
|
||||||
auto& regs = update_render_targets_regs_;
|
auto& regs = update_render_targets_regs_;
|
||||||
|
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
|
@ -1497,7 +1499,7 @@ bool CommandProcessor::UpdateRenderTargets(DrawCommand* draw_command) {
|
||||||
SetShadowRegister(regs.rb_stencilrefmask, XE_GPU_REG_RB_STENCILREFMASK);
|
SetShadowRegister(regs.rb_stencilrefmask, XE_GPU_REG_RB_STENCILREFMASK);
|
||||||
dirty |= SetShadowRegister(regs.rb_depth_info, XE_GPU_REG_RB_DEPTH_INFO);
|
dirty |= SetShadowRegister(regs.rb_depth_info, XE_GPU_REG_RB_DEPTH_INFO);
|
||||||
if (!dirty) {
|
if (!dirty) {
|
||||||
return true;
|
return UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCOPE_profile_cpu_f("gpu");
|
SCOPE_profile_cpu_f("gpu");
|
||||||
|
@ -1574,14 +1576,16 @@ bool CommandProcessor::UpdateRenderTargets(DrawCommand* draw_command) {
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, cached_framebuffer->framebuffer);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, cached_framebuffer->framebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return UpdateStatus::kMismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::UpdateState(DrawCommand* draw_command) {
|
CommandProcessor::UpdateStatus CommandProcessor::UpdateState(
|
||||||
SCOPE_profile_cpu_f("gpu");
|
DrawCommand* draw_command) {
|
||||||
auto& regs = *register_file_;
|
auto& regs = *register_file_;
|
||||||
auto state_data = draw_command->state_data;
|
auto state_data = draw_command->state_data;
|
||||||
|
|
||||||
|
bool mismatch = false;
|
||||||
|
|
||||||
// Alpha testing -- ALPHAREF, ALPHAFUNC, ALPHATESTENABLE
|
// Alpha testing -- ALPHAREF, ALPHAFUNC, ALPHATESTENABLE
|
||||||
// Deprecated in GL, implemented in shader.
|
// Deprecated in GL, implemented in shader.
|
||||||
// if(ALPHATESTENABLE && frag_out.a [<=/ALPHAFUNC] ALPHAREF) discard;
|
// if(ALPHATESTENABLE && frag_out.a [<=/ALPHAFUNC] ALPHAREF) discard;
|
||||||
|
@ -1591,19 +1595,35 @@ bool CommandProcessor::UpdateState(DrawCommand* draw_command) {
|
||||||
state_data->alpha_test.y = float(color_control & 0x3); // ALPHAFUNC
|
state_data->alpha_test.y = float(color_control & 0x3); // ALPHAFUNC
|
||||||
state_data->alpha_test.z = regs[XE_GPU_REG_RB_ALPHA_REF].f32;
|
state_data->alpha_test.z = regs[XE_GPU_REG_RB_ALPHA_REF].f32;
|
||||||
|
|
||||||
UpdateViewportState(draw_command);
|
#define CHECK_UPDATE_STATUS(status, mismatch, error_message) \
|
||||||
UpdateRasterizerState(draw_command);
|
{ \
|
||||||
UpdateBlendState(draw_command);
|
if (status == UpdateStatus::kError) { \
|
||||||
UpdateDepthStencilState(draw_command);
|
PLOGE(error_message); \
|
||||||
|
return status; \
|
||||||
|
} else if (status == UpdateStatus::kMismatch) { \
|
||||||
|
mismatch = true; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
UpdateStatus status;
|
||||||
|
status = UpdateViewportState(draw_command);
|
||||||
|
CHECK_UPDATE_STATUS(status, mismatch, "Unable to update viewport state");
|
||||||
|
status = UpdateRasterizerState(draw_command);
|
||||||
|
CHECK_UPDATE_STATUS(status, mismatch, "Unable to update rasterizer state");
|
||||||
|
status = UpdateBlendState(draw_command);
|
||||||
|
CHECK_UPDATE_STATUS(status, mismatch, "Unable to update blend state");
|
||||||
|
status = UpdateDepthStencilState(draw_command);
|
||||||
|
CHECK_UPDATE_STATUS(status, mismatch, "Unable to update depth/stencil state");
|
||||||
|
|
||||||
|
return mismatch ? UpdateStatus::kMismatch : UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::UpdateViewportState(DrawCommand* draw_command) {
|
CommandProcessor::UpdateStatus CommandProcessor::UpdateViewportState(
|
||||||
|
DrawCommand* draw_command) {
|
||||||
auto& regs = *register_file_;
|
auto& regs = *register_file_;
|
||||||
auto state_data = draw_command->state_data;
|
auto state_data = draw_command->state_data;
|
||||||
|
|
||||||
SCOPE_profile_cpu_f("gpu");
|
// NOTE: we don't track state here as this is all cheap to update (ish).
|
||||||
|
|
||||||
// Much of this state machine is extracted from:
|
// Much of this state machine is extracted from:
|
||||||
// https://github.com/freedreno/mesa/blob/master/src/mesa/drivers/dri/r200/r200_state.c
|
// https://github.com/freedreno/mesa/blob/master/src/mesa/drivers/dri/r200/r200_state.c
|
||||||
|
@ -1701,10 +1721,11 @@ bool CommandProcessor::UpdateViewportState(DrawCommand* draw_command) {
|
||||||
bool dx_clip = ((clip_control >> 20) & 0x1) == 0x1;
|
bool dx_clip = ((clip_control >> 20) & 0x1) == 0x1;
|
||||||
// assert_true(dx_clip);
|
// assert_true(dx_clip);
|
||||||
|
|
||||||
return true;
|
return UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::UpdateRasterizerState(DrawCommand* draw_command) {
|
CommandProcessor::UpdateStatus CommandProcessor::UpdateRasterizerState(
|
||||||
|
DrawCommand* draw_command) {
|
||||||
auto& regs = update_rasterizer_state_regs_;
|
auto& regs = update_rasterizer_state_regs_;
|
||||||
|
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
|
@ -1715,7 +1736,7 @@ bool CommandProcessor::UpdateRasterizerState(DrawCommand* draw_command) {
|
||||||
dirty |= SetShadowRegister(regs.pa_sc_screen_scissor_br,
|
dirty |= SetShadowRegister(regs.pa_sc_screen_scissor_br,
|
||||||
XE_GPU_REG_PA_SC_SCREEN_SCISSOR_BR);
|
XE_GPU_REG_PA_SC_SCREEN_SCISSOR_BR);
|
||||||
if (!dirty) {
|
if (!dirty) {
|
||||||
return true;
|
return UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCOPE_profile_cpu_f("gpu");
|
SCOPE_profile_cpu_f("gpu");
|
||||||
|
@ -1765,10 +1786,11 @@ bool CommandProcessor::UpdateRasterizerState(DrawCommand* draw_command) {
|
||||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
|
||||||
return true;
|
return UpdateStatus::kMismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::UpdateBlendState(DrawCommand* draw_command) {
|
CommandProcessor::UpdateStatus CommandProcessor::UpdateBlendState(
|
||||||
|
DrawCommand* draw_command) {
|
||||||
auto& regs = update_blend_state_regs_;
|
auto& regs = update_blend_state_regs_;
|
||||||
|
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
|
@ -1785,7 +1807,7 @@ bool CommandProcessor::UpdateBlendState(DrawCommand* draw_command) {
|
||||||
dirty |= SetShadowRegister(regs.rb_blend_rgba[2], XE_GPU_REG_RB_BLEND_BLUE);
|
dirty |= SetShadowRegister(regs.rb_blend_rgba[2], XE_GPU_REG_RB_BLEND_BLUE);
|
||||||
dirty |= SetShadowRegister(regs.rb_blend_rgba[3], XE_GPU_REG_RB_BLEND_ALPHA);
|
dirty |= SetShadowRegister(regs.rb_blend_rgba[3], XE_GPU_REG_RB_BLEND_ALPHA);
|
||||||
if (!dirty) {
|
if (!dirty) {
|
||||||
return true;
|
return UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCOPE_profile_cpu_f("gpu");
|
SCOPE_profile_cpu_f("gpu");
|
||||||
|
@ -1849,10 +1871,11 @@ bool CommandProcessor::UpdateBlendState(DrawCommand* draw_command) {
|
||||||
glBlendColor(regs.rb_blend_rgba[0], regs.rb_blend_rgba[1],
|
glBlendColor(regs.rb_blend_rgba[0], regs.rb_blend_rgba[1],
|
||||||
regs.rb_blend_rgba[2], regs.rb_blend_rgba[3]);
|
regs.rb_blend_rgba[2], regs.rb_blend_rgba[3]);
|
||||||
|
|
||||||
return true;
|
return UpdateStatus::kMismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::UpdateDepthStencilState(DrawCommand* draw_command) {
|
CommandProcessor::UpdateStatus CommandProcessor::UpdateDepthStencilState(
|
||||||
|
DrawCommand* draw_command) {
|
||||||
auto& regs = update_depth_stencil_state_regs_;
|
auto& regs = update_depth_stencil_state_regs_;
|
||||||
|
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
|
@ -1860,7 +1883,7 @@ bool CommandProcessor::UpdateDepthStencilState(DrawCommand* draw_command) {
|
||||||
dirty |=
|
dirty |=
|
||||||
SetShadowRegister(regs.rb_stencilrefmask, XE_GPU_REG_RB_STENCILREFMASK);
|
SetShadowRegister(regs.rb_stencilrefmask, XE_GPU_REG_RB_STENCILREFMASK);
|
||||||
if (!dirty) {
|
if (!dirty) {
|
||||||
return true;
|
return UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCOPE_profile_cpu_f("gpu");
|
SCOPE_profile_cpu_f("gpu");
|
||||||
|
@ -1943,10 +1966,11 @@ bool CommandProcessor::UpdateDepthStencilState(DrawCommand* draw_command) {
|
||||||
stencil_op_map[(regs.rb_depthcontrol & 0x0001C000) >> 14]);
|
stencil_op_map[(regs.rb_depthcontrol & 0x0001C000) >> 14]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return UpdateStatus::kMismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::UpdateConstants(DrawCommand* draw_command) {
|
CommandProcessor::UpdateStatus CommandProcessor::UpdateConstants(
|
||||||
|
DrawCommand* draw_command) {
|
||||||
auto& regs = *register_file_;
|
auto& regs = *register_file_;
|
||||||
auto state_data = draw_command->state_data;
|
auto state_data = draw_command->state_data;
|
||||||
|
|
||||||
|
@ -1961,10 +1985,11 @@ bool CommandProcessor::UpdateConstants(DrawCommand* draw_command) {
|
||||||
sizeof(state_data->float_consts) + sizeof(state_data->fetch_consts) +
|
sizeof(state_data->float_consts) + sizeof(state_data->fetch_consts) +
|
||||||
sizeof(state_data->loop_consts) + sizeof(state_data->bool_consts));
|
sizeof(state_data->loop_consts) + sizeof(state_data->bool_consts));
|
||||||
|
|
||||||
return true;
|
return UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::UpdateShaders(DrawCommand* draw_command) {
|
CommandProcessor::UpdateStatus CommandProcessor::UpdateShaders(
|
||||||
|
DrawCommand* draw_command) {
|
||||||
auto& regs = update_shaders_regs_;
|
auto& regs = update_shaders_regs_;
|
||||||
auto& cmd = *draw_command;
|
auto& cmd = *draw_command;
|
||||||
|
|
||||||
|
@ -1974,7 +1999,7 @@ bool CommandProcessor::UpdateShaders(DrawCommand* draw_command) {
|
||||||
dirty |= regs.pixel_shader != active_pixel_shader_;
|
dirty |= regs.pixel_shader != active_pixel_shader_;
|
||||||
dirty |= regs.prim_type != cmd.prim_type;
|
dirty |= regs.prim_type != cmd.prim_type;
|
||||||
if (!dirty) {
|
if (!dirty) {
|
||||||
return true;
|
return UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
regs.vertex_shader = active_vertex_shader_;
|
regs.vertex_shader = active_vertex_shader_;
|
||||||
regs.pixel_shader = active_pixel_shader_;
|
regs.pixel_shader = active_pixel_shader_;
|
||||||
|
@ -1987,21 +2012,21 @@ bool CommandProcessor::UpdateShaders(DrawCommand* draw_command) {
|
||||||
if (!active_vertex_shader_->has_prepared()) {
|
if (!active_vertex_shader_->has_prepared()) {
|
||||||
if (!active_vertex_shader_->PrepareVertexShader(program_cntl)) {
|
if (!active_vertex_shader_->PrepareVertexShader(program_cntl)) {
|
||||||
XELOGE("Unable to prepare vertex shader");
|
XELOGE("Unable to prepare vertex shader");
|
||||||
return false;
|
return UpdateStatus::kError;
|
||||||
}
|
}
|
||||||
} else if (!active_vertex_shader_->is_valid()) {
|
} else if (!active_vertex_shader_->is_valid()) {
|
||||||
XELOGE("Vertex shader invalid");
|
XELOGE("Vertex shader invalid");
|
||||||
return false;
|
return UpdateStatus::kError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!active_pixel_shader_->has_prepared()) {
|
if (!active_pixel_shader_->has_prepared()) {
|
||||||
if (!active_pixel_shader_->PreparePixelShader(program_cntl)) {
|
if (!active_pixel_shader_->PreparePixelShader(program_cntl)) {
|
||||||
XELOGE("Unable to prepare pixel shader");
|
XELOGE("Unable to prepare pixel shader");
|
||||||
return false;
|
return UpdateStatus::kError;
|
||||||
}
|
}
|
||||||
} else if (!active_pixel_shader_->is_valid()) {
|
} else if (!active_pixel_shader_->is_valid()) {
|
||||||
XELOGE("Pixel shader invalid");
|
XELOGE("Pixel shader invalid");
|
||||||
return false;
|
return UpdateStatus::kError;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint vertex_program = active_vertex_shader_->program();
|
GLuint vertex_program = active_vertex_shader_->program();
|
||||||
|
@ -2065,16 +2090,17 @@ bool CommandProcessor::UpdateShaders(DrawCommand* draw_command) {
|
||||||
}
|
}
|
||||||
glBindProgramPipeline(pipeline);
|
glBindProgramPipeline(pipeline);
|
||||||
|
|
||||||
return true;
|
return UpdateStatus::kMismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::PopulateIndexBuffer(DrawCommand* draw_command) {
|
CommandProcessor::UpdateStatus CommandProcessor::PopulateIndexBuffer(
|
||||||
|
DrawCommand* draw_command) {
|
||||||
auto& cmd = *draw_command;
|
auto& cmd = *draw_command;
|
||||||
|
|
||||||
auto& info = cmd.index_buffer;
|
auto& info = cmd.index_buffer;
|
||||||
if (!cmd.index_count || !info.address) {
|
if (!cmd.index_count || !info.address) {
|
||||||
// No index buffer or auto draw.
|
// No index buffer or auto draw.
|
||||||
return true;
|
return UpdateStatus::kMismatch; // ?
|
||||||
}
|
}
|
||||||
|
|
||||||
SCOPE_profile_cpu_f("gpu");
|
SCOPE_profile_cpu_f("gpu");
|
||||||
|
@ -2109,10 +2135,11 @@ bool CommandProcessor::PopulateIndexBuffer(DrawCommand* draw_command) {
|
||||||
}
|
}
|
||||||
scratch_buffer_.Commit(std::move(allocation));
|
scratch_buffer_.Commit(std::move(allocation));
|
||||||
|
|
||||||
return true;
|
return UpdateStatus::kMismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::PopulateVertexBuffers(DrawCommand* draw_command) {
|
CommandProcessor::UpdateStatus CommandProcessor::PopulateVertexBuffers(
|
||||||
|
DrawCommand* draw_command) {
|
||||||
SCOPE_profile_cpu_f("gpu");
|
SCOPE_profile_cpu_f("gpu");
|
||||||
auto& regs = *register_file_;
|
auto& regs = *register_file_;
|
||||||
auto& cmd = *draw_command;
|
auto& cmd = *draw_command;
|
||||||
|
@ -2235,13 +2262,16 @@ bool CommandProcessor::PopulateVertexBuffers(DrawCommand* draw_command) {
|
||||||
scratch_buffer_.Commit(std::move(allocation));
|
scratch_buffer_.Commit(std::move(allocation));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return UpdateStatus::kMismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::PopulateSamplers(DrawCommand* draw_command) {
|
CommandProcessor::UpdateStatus CommandProcessor::PopulateSamplers(
|
||||||
|
DrawCommand* draw_command) {
|
||||||
SCOPE_profile_cpu_f("gpu");
|
SCOPE_profile_cpu_f("gpu");
|
||||||
auto& regs = *register_file_;
|
auto& regs = *register_file_;
|
||||||
|
|
||||||
|
bool mismatch = false;
|
||||||
|
|
||||||
// VS and PS samplers are shared, but may be used exclusively.
|
// VS and PS samplers are shared, but may be used exclusively.
|
||||||
// We walk each and setup lazily.
|
// We walk each and setup lazily.
|
||||||
bool has_setup_sampler[32] = {false};
|
bool has_setup_sampler[32] = {false};
|
||||||
|
@ -2254,8 +2284,11 @@ bool CommandProcessor::PopulateSamplers(DrawCommand* draw_command) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
has_setup_sampler[desc.fetch_slot] = true;
|
has_setup_sampler[desc.fetch_slot] = true;
|
||||||
if (!PopulateSampler(draw_command, desc)) {
|
auto status = PopulateSampler(draw_command, desc);
|
||||||
return false;
|
if (status == UpdateStatus::kError) {
|
||||||
|
return status;
|
||||||
|
} else if (status == UpdateStatus::kMismatch) {
|
||||||
|
mismatch = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2267,16 +2300,19 @@ bool CommandProcessor::PopulateSamplers(DrawCommand* draw_command) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
has_setup_sampler[desc.fetch_slot] = true;
|
has_setup_sampler[desc.fetch_slot] = true;
|
||||||
if (!PopulateSampler(draw_command, desc)) {
|
auto status = PopulateSampler(draw_command, desc);
|
||||||
return false;
|
if (status == UpdateStatus::kError) {
|
||||||
|
return UpdateStatus::kError;
|
||||||
|
} else if (status == UpdateStatus::kMismatch) {
|
||||||
|
mismatch = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return mismatch ? UpdateStatus::kMismatch : UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::PopulateSampler(DrawCommand* draw_command,
|
CommandProcessor::UpdateStatus CommandProcessor::PopulateSampler(
|
||||||
const Shader::SamplerDesc& desc) {
|
DrawCommand* draw_command, const Shader::SamplerDesc& desc) {
|
||||||
auto& regs = *register_file_;
|
auto& regs = *register_file_;
|
||||||
int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + desc.fetch_slot * 6;
|
int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + desc.fetch_slot * 6;
|
||||||
auto group = reinterpret_cast<const xe_gpu_fetch_group_t*>(®s.values[r]);
|
auto group = reinterpret_cast<const xe_gpu_fetch_group_t*>(®s.values[r]);
|
||||||
|
@ -2287,38 +2323,38 @@ bool CommandProcessor::PopulateSampler(DrawCommand* draw_command,
|
||||||
draw_command->state_data->texture_samplers[desc.fetch_slot] = 0;
|
draw_command->state_data->texture_samplers[desc.fetch_slot] = 0;
|
||||||
|
|
||||||
if (FLAGS_disable_textures) {
|
if (FLAGS_disable_textures) {
|
||||||
return true;
|
return UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ?
|
// ?
|
||||||
if (!fetch.type) {
|
if (!fetch.type) {
|
||||||
return true;
|
return UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
assert_true(fetch.type == 0x2);
|
assert_true(fetch.type == 0x2);
|
||||||
|
|
||||||
TextureInfo texture_info;
|
TextureInfo texture_info;
|
||||||
if (!TextureInfo::Prepare(fetch, &texture_info)) {
|
if (!TextureInfo::Prepare(fetch, &texture_info)) {
|
||||||
XELOGE("Unable to parse texture fetcher info");
|
XELOGE("Unable to parse texture fetcher info");
|
||||||
return true; // invalid texture used
|
return UpdateStatus::kCompatible; // invalid texture used
|
||||||
}
|
}
|
||||||
SamplerInfo sampler_info;
|
SamplerInfo sampler_info;
|
||||||
if (!SamplerInfo::Prepare(fetch, desc.tex_fetch, &sampler_info)) {
|
if (!SamplerInfo::Prepare(fetch, desc.tex_fetch, &sampler_info)) {
|
||||||
XELOGE("Unable to parse sampler info");
|
XELOGE("Unable to parse sampler info");
|
||||||
return true; // invalid texture used
|
return UpdateStatus::kCompatible; // invalid texture used
|
||||||
}
|
}
|
||||||
|
|
||||||
auto entry_view = texture_cache_.Demand(texture_info, sampler_info);
|
auto entry_view = texture_cache_.Demand(texture_info, sampler_info);
|
||||||
if (!entry_view) {
|
if (!entry_view) {
|
||||||
// Unable to create/fetch/etc.
|
// Unable to create/fetch/etc.
|
||||||
XELOGE("Failed to demand texture");
|
XELOGE("Failed to demand texture");
|
||||||
return true;
|
return UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shaders will use bindless to fetch right from it.
|
// Shaders will use bindless to fetch right from it.
|
||||||
draw_command->state_data->texture_samplers[desc.fetch_slot] =
|
draw_command->state_data->texture_samplers[desc.fetch_slot] =
|
||||||
entry_view->texture_sampler_handle;
|
entry_view->texture_sampler_handle;
|
||||||
|
|
||||||
return true;
|
return UpdateStatus::kCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandProcessor::IssueCopy(DrawCommand* draw_command) {
|
bool CommandProcessor::IssueCopy(DrawCommand* draw_command) {
|
||||||
|
|
|
@ -129,6 +129,12 @@ class CommandProcessor {
|
||||||
private:
|
private:
|
||||||
class RingbufferReader;
|
class RingbufferReader;
|
||||||
|
|
||||||
|
enum class UpdateStatus {
|
||||||
|
kCompatible,
|
||||||
|
kMismatch,
|
||||||
|
kError,
|
||||||
|
};
|
||||||
|
|
||||||
struct CachedFramebuffer {
|
struct CachedFramebuffer {
|
||||||
GLuint color_targets[4];
|
GLuint color_targets[4];
|
||||||
GLuint depth_target;
|
GLuint depth_target;
|
||||||
|
@ -235,18 +241,18 @@ class CommandProcessor {
|
||||||
|
|
||||||
void PrepareDraw(DrawCommand* draw_command);
|
void PrepareDraw(DrawCommand* draw_command);
|
||||||
bool IssueDraw(DrawCommand* draw_command);
|
bool IssueDraw(DrawCommand* draw_command);
|
||||||
bool UpdateRenderTargets(DrawCommand* draw_command);
|
UpdateStatus UpdateRenderTargets(DrawCommand* draw_command);
|
||||||
bool UpdateState(DrawCommand* draw_command);
|
UpdateStatus UpdateState(DrawCommand* draw_command);
|
||||||
bool UpdateViewportState(DrawCommand* draw_command);
|
UpdateStatus UpdateViewportState(DrawCommand* draw_command);
|
||||||
bool UpdateRasterizerState(DrawCommand* draw_command);
|
UpdateStatus UpdateRasterizerState(DrawCommand* draw_command);
|
||||||
bool UpdateBlendState(DrawCommand* draw_command);
|
UpdateStatus UpdateBlendState(DrawCommand* draw_command);
|
||||||
bool UpdateDepthStencilState(DrawCommand* draw_command);
|
UpdateStatus UpdateDepthStencilState(DrawCommand* draw_command);
|
||||||
bool UpdateConstants(DrawCommand* draw_command);
|
UpdateStatus UpdateConstants(DrawCommand* draw_command);
|
||||||
bool UpdateShaders(DrawCommand* draw_command);
|
UpdateStatus UpdateShaders(DrawCommand* draw_command);
|
||||||
bool PopulateIndexBuffer(DrawCommand* draw_command);
|
UpdateStatus PopulateIndexBuffer(DrawCommand* draw_command);
|
||||||
bool PopulateVertexBuffers(DrawCommand* draw_command);
|
UpdateStatus PopulateVertexBuffers(DrawCommand* draw_command);
|
||||||
bool PopulateSamplers(DrawCommand* draw_command);
|
UpdateStatus PopulateSamplers(DrawCommand* draw_command);
|
||||||
bool PopulateSampler(DrawCommand* draw_command,
|
UpdateStatus PopulateSampler(DrawCommand* draw_command,
|
||||||
const Shader::SamplerDesc& desc);
|
const Shader::SamplerDesc& desc);
|
||||||
bool IssueCopy(DrawCommand* draw_command);
|
bool IssueCopy(DrawCommand* draw_command);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue