st/mesa: add support for advanced blend when fb can be fetched from
authorIlia Mirkin <imirkin@alum.mit.edu>
Mon, 2 Jan 2017 04:47:25 +0000 (23:47 -0500)
committerIlia Mirkin <imirkin@alum.mit.edu>
Tue, 17 Jan 2017 02:13:09 +0000 (21:13 -0500)
This implements support for emitting FBFETCH ops, using the existing
lowering pass for advanced blend logic, and disabling hw blend when
advanced blending is enabled.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/mesa/state_tracker/st_atom_blend.c
src/mesa/state_tracker/st_cb_texturebarrier.c
src/mesa/state_tracker/st_extensions.c
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index b8d65bde29ebf48ace9f6835932924a453604952..f76cfab943795554ccc833dc971e6b9269e5b242 100644 (file)
@@ -205,7 +205,7 @@ update_blend( struct st_context *st )
       blend->logicop_enable = 1;
       blend->logicop_func = translate_logicop(ctx->Color.LogicOp);
    }
-   else if (ctx->Color.BlendEnabled) {
+   else if (ctx->Color.BlendEnabled && !ctx->Color._AdvancedBlendMode) {
       /* blending enabled */
       for (i = 0, j = 0; i < num_state; i++) {
 
index 7fd1cbd1d7c37c41e365028ca3211489e44b4971..29cd37c16ce77c5f3931729bc02d5b5e44a05855 100644 (file)
@@ -54,6 +54,18 @@ st_TextureBarrier(struct gl_context *ctx)
 }
 
 
+/**
+ * Called via ctx->Driver.BlendBarrier()
+ */
+static void
+st_BlendBarrier(struct gl_context *ctx)
+{
+   struct pipe_context *pipe = st_context(ctx)->pipe;
+
+   pipe->texture_barrier(pipe, PIPE_TEXTURE_BARRIER_FRAMEBUFFER);
+}
+
+
 /**
  * Called via ctx->Driver.MemoryBarrier()
  */
@@ -118,5 +130,6 @@ st_MemoryBarrier(struct gl_context *ctx, GLbitfield barriers)
 void st_init_texture_barrier_functions(struct dd_function_table *functions)
 {
    functions->TextureBarrier = st_TextureBarrier;
+   functions->BlendBarrier = st_BlendBarrier;
    functions->MemoryBarrier = st_MemoryBarrier;
 }
index 7ff571603ba2afb1d8492dcf1263614733d846f1..5ccc5d9b0e2f6ffbba4469e2b3ca69b80239e0fc 100644 (file)
@@ -616,6 +616,8 @@ void st_init_extensions(struct pipe_screen *screen,
       { o(ARB_transform_feedback2),          PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME       },
       { o(ARB_transform_feedback3),          PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS },
 
+      { o(KHR_blend_equation_advanced),      PIPE_CAP_TGSI_FS_FBFETCH                  },
+
       { o(EXT_blend_equation_separate),      PIPE_CAP_BLEND_EQUATION_SEPARATE          },
       { o(EXT_depth_bounds_test),            PIPE_CAP_DEPTH_BOUNDS_TEST                },
       { o(EXT_draw_buffers2),                PIPE_CAP_INDEP_BLEND_ENABLE               },
index 9356707f16f497fb3aec552381dc95d6674bc606..4bdb3a6532ee737aaa10f5f288cd416196d2fd26 100644 (file)
@@ -2520,10 +2520,19 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
          else
             decl->size = type_size(var->type);
 
-         entry = new(mem_ctx) variable_storage(var,
-                                               PROGRAM_OUTPUT,
-                                               decl->mesa_index,
-                                               decl->array_id);
+         if (var->data.fb_fetch_output) {
+            st_dst_reg dst = st_dst_reg(get_temp(var->type));
+            st_src_reg src = st_src_reg(PROGRAM_OUTPUT, decl->mesa_index,
+                                        var->type, component, decl->array_id);
+            emit_asm(NULL, TGSI_OPCODE_FBFETCH, dst, src);
+            entry = new(mem_ctx) variable_storage(var, dst.file, dst.index,
+                                                  dst.array_id);
+         } else {
+            entry = new(mem_ctx) variable_storage(var,
+                                                  PROGRAM_OUTPUT,
+                                                  decl->mesa_index,
+                                                  decl->array_id);
+         }
          entry->component = component;
 
          this->variables.push_tail(entry);
@@ -6855,8 +6864,9 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
       if (prog->_LinkedShaders[i] == NULL)
          continue;
 
-      exec_list *ir = prog->_LinkedShaders[i]->ir;
-      gl_shader_stage stage = prog->_LinkedShaders[i]->Stage;
+      struct gl_linked_shader *shader = prog->_LinkedShaders[i];
+      exec_list *ir = shader->ir;
+      gl_shader_stage stage = shader->Stage;
       const struct gl_shader_compiler_options *options =
             &ctx->Const.ShaderCompilerOptions[stage];
       enum pipe_shader_type ptarget = st_shader_stage_to_ptarget(stage);
@@ -6872,7 +6882,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
        */
       if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput ||
           options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) {
-         lower_variable_index_to_cond_assign(prog->_LinkedShaders[i]->Stage, ir,
+         lower_variable_index_to_cond_assign(stage, ir,
                                              options->EmitNoIndirectInput,
                                              options->EmitNoIndirectOutput,
                                              options->EmitNoIndirectTemp,
@@ -6902,6 +6912,10 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
       if (!pscreen->get_param(pscreen, PIPE_CAP_TEXTURE_GATHER_OFFSETS))
          lower_offset_arrays(ir);
       do_mat_op_to_vec(ir);
+
+      if (stage == MESA_SHADER_FRAGMENT)
+         lower_blend_equation_advanced(shader);
+
       lower_instructions(ir,
                          MOD_TO_FLOOR |
                          DIV_TO_MUL_RCP |