Пример #1
0
static inline void output_frame(uint64_t *cur_time, uint64_t interval)
{
	struct obs_core_video *video = &obs->video;
	int cur_texture  = video->cur_texture;
	int prev_texture = cur_texture == 0 ? NUM_TEXTURES-1 : cur_texture-1;
	struct video_data frame;
	bool frame_ready;

	memset(&frame, 0, sizeof(struct video_data));

	gs_enter_context(video->graphics);
	render_video(video, cur_texture, prev_texture);
	frame_ready = download_frame(video, prev_texture, &frame);
	gs_flush();
	gs_leave_context();

	if (frame_ready) {
		struct obs_vframe_info vframe_info;
		circlebuf_pop_front(&video->vframe_info_buffer, &vframe_info,
				sizeof(vframe_info));

		frame.timestamp = vframe_info.timestamp;
		output_video_data(video, &frame, vframe_info.count);
	}

	if (++video->cur_texture == NUM_TEXTURES)
		video->cur_texture = 0;

	video_sleep(video, cur_time, interval);
}
Пример #2
0
static inline void render_video(struct obs_core_video *video,
		bool raw_active, const bool gpu_active,
		int cur_texture, int prev_texture)
{
	gs_begin_scene();

	gs_enable_depth_test(false);
	gs_set_cull_mode(GS_NEITHER);

	render_main_texture(video, cur_texture);

	if (raw_active || gpu_active) {
		render_output_texture(video, cur_texture, prev_texture);

#ifdef _WIN32
		if (gpu_active) {
			gs_flush();
		}
#endif
	}

	if (raw_active || gpu_active) {
		if (video->gpu_conversion) {
			if (video->using_nv12_tex)
				render_convert_texture_nv12(video,
						cur_texture, prev_texture);
			else
				render_convert_texture(video,
						cur_texture, prev_texture);
		}

#ifdef _WIN32
		if (gpu_active) {
			gs_flush();
			output_gpu_encoders(video, raw_active, prev_texture);
		}
#endif
		if (raw_active)
			stage_output_texture(video, cur_texture, prev_texture);
	}

	gs_set_render_target(NULL, NULL);
	gs_enable_blending(true);

	gs_end_scene();
}
Пример #3
0
static void gs_point(struct draw_geometry_shader *shader,
                     int idx)
{
   unsigned indices[1];

   indices[0] = idx;

   draw_fetch_gs_input(shader, indices, 1, 0);
   ++shader->in_prim_idx;

   gs_flush(shader, 1);
}
Пример #4
0
static void gs_line(struct draw_geometry_shader *shader,
                    int i0, int i1)
{
   unsigned indices[2];

   indices[0] = i0;
   indices[1] = i1;

   draw_fetch_gs_input(shader, indices, 2, 0);
   ++shader->in_prim_idx;

   gs_flush(shader, 1);
}
Пример #5
0
static void gs_tri(struct draw_geometry_shader *shader,
                   int i0, int i1, int i2)
{
   unsigned indices[3];

   indices[0] = i0;
   indices[1] = i1;
   indices[2] = i2;

   draw_fetch_gs_input(shader, indices, 3, 0);
   ++shader->in_prim_idx;

   gs_flush(shader, 1);
}
Пример #6
0
static void gs_point(struct draw_geometry_shader *shader,
                     int idx)
{
   unsigned indices[1];

   indices[0] = idx;

   shader->fetch_inputs(shader, indices, 1,
                        shader->fetched_prim_count);
   ++shader->in_prim_idx;
   ++shader->fetched_prim_count;

   if (draw_gs_should_flush(shader))
      gs_flush(shader);
}
Пример #7
0
static void gs_line_adj(struct draw_geometry_shader *shader,
                        int i0, int i1, int i2, int i3)
{
   unsigned indices[4];

   indices[0] = i0;
   indices[1] = i1;
   indices[2] = i2;
   indices[3] = i3;

   draw_fetch_gs_input(shader, indices, 4, 0);
   ++shader->in_prim_idx;

   gs_flush(shader, 1);
}
Пример #8
0
static void gs_line(struct draw_geometry_shader *shader,
                    int i0, int i1)
{
   unsigned indices[2];

   indices[0] = i0;
   indices[1] = i1;

   shader->fetch_inputs(shader, indices, 2,
                        shader->fetched_prim_count);
   ++shader->in_prim_idx;
   ++shader->fetched_prim_count;
   
   if (draw_gs_should_flush(shader))   
      gs_flush(shader);
}
Пример #9
0
static inline void output_frame(bool raw_active, const bool gpu_active)
{
	struct obs_core_video *video = &obs->video;
	int cur_texture  = video->cur_texture;
	int prev_texture = cur_texture == 0 ? NUM_TEXTURES-1 : cur_texture-1;
	struct video_data frame;
	bool active = raw_active || gpu_active;
	bool frame_ready;

	memset(&frame, 0, sizeof(struct video_data));

	profile_start(output_frame_gs_context_name);
	gs_enter_context(video->graphics);

	profile_start(output_frame_render_video_name);
	render_video(video, raw_active, gpu_active, cur_texture, prev_texture);
	profile_end(output_frame_render_video_name);

	if (raw_active) {
		profile_start(output_frame_download_frame_name);
		frame_ready = download_frame(video, prev_texture, &frame);
		profile_end(output_frame_download_frame_name);
	}

	profile_start(output_frame_gs_flush_name);
	gs_flush();
	profile_end(output_frame_gs_flush_name);

	gs_leave_context();
	profile_end(output_frame_gs_context_name);

	if (raw_active && frame_ready) {
		struct obs_vframe_info vframe_info;
		circlebuf_pop_front(&video->vframe_info_buffer, &vframe_info,
				sizeof(vframe_info));

		frame.timestamp = vframe_info.timestamp;
		profile_start(output_frame_output_video_data_name);
		output_video_data(video, &frame, vframe_info.count);
		profile_end(output_frame_output_video_data_name);
	}

	if (++video->cur_texture == NUM_TEXTURES)
		video->cur_texture = 0;
}
Пример #10
0
static void gs_line_adj(struct draw_geometry_shader *shader,
                        int i0, int i1, int i2, int i3)
{
   unsigned indices[4];

   indices[0] = i0;
   indices[1] = i1;
   indices[2] = i2;
   indices[3] = i3;

   shader->fetch_inputs(shader, indices, 4,
                        shader->fetched_prim_count);
   ++shader->in_prim_idx;
   ++shader->fetched_prim_count;

   if (draw_gs_should_flush(shader))
      gs_flush(shader);
}
Пример #11
0
static void gs_tri_adj(struct draw_geometry_shader *shader,
                       int i0, int i1, int i2,
                       int i3, int i4, int i5)
{
   unsigned indices[6];

   indices[0] = i0;
   indices[1] = i1;
   indices[2] = i2;
   indices[3] = i3;
   indices[4] = i4;
   indices[5] = i5;

   draw_fetch_gs_input(shader, indices, 6, 0);
   ++shader->in_prim_idx;

   gs_flush(shader, 1);
}
Пример #12
0
/**
 * Execute geometry shader.
 */
int draw_geometry_shader_run(struct draw_geometry_shader *shader,
                             const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
                             const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS],
                             const struct draw_vertex_info *input_verts,
                             const struct draw_prim_info *input_prim,
                             const struct tgsi_shader_info *input_info,
                             struct draw_vertex_info *output_verts,
                             struct draw_prim_info *output_prims )
{
   const float (*input)[4] = (const float (*)[4])input_verts->verts->data;
   unsigned input_stride = input_verts->vertex_size;
   unsigned num_outputs = draw_total_gs_outputs(shader->draw);
   unsigned vertex_size = sizeof(struct vertex_header) + num_outputs * 4 * sizeof(float);
   unsigned num_input_verts = input_prim->linear ?
      input_verts->count :
      input_prim->count;
   unsigned num_in_primitives =
      align(
         MAX2(u_decomposed_prims_for_vertices(input_prim->prim,
                                              num_input_verts),
              u_decomposed_prims_for_vertices(shader->input_primitive,
                                              num_input_verts)),
         shader->vector_length);
   unsigned max_out_prims =
      u_decomposed_prims_for_vertices(shader->output_primitive,
                                      shader->max_output_vertices)
      * num_in_primitives;

   //Assume at least one primitive
   max_out_prims = MAX2(max_out_prims, 1);


   output_verts->vertex_size = vertex_size;
   output_verts->stride = output_verts->vertex_size;
   /* we allocate exactly one extra vertex per primitive to allow the GS to emit
    * overflown vertices into some area where they won't harm anyone */
   output_verts->verts =
      (struct vertex_header *)MALLOC(output_verts->vertex_size *
                                     max_out_prims *
                                     shader->primitive_boundary);

#if 0
   debug_printf("%s count = %d (in prims # = %d)\n",
                __FUNCTION__, num_input_verts, num_in_primitives);
   debug_printf("\tlinear = %d, prim_info->count = %d\n",
                input_prim->linear, input_prim->count);
   debug_printf("\tprim pipe = %s, shader in = %s, shader out = %s, max out = %d\n",
                u_prim_name(input_prim->prim),
                u_prim_name(shader->input_primitive),
                u_prim_name(shader->output_primitive),
                shader->max_output_vertices);
#endif

   shader->emitted_vertices = 0;
   shader->emitted_primitives = 0;
   shader->vertex_size = vertex_size;
   shader->tmp_output = (float (*)[4])output_verts->verts->data;
   shader->fetched_prim_count = 0;
   shader->input_vertex_stride = input_stride;
   shader->input = input;
   shader->input_info = input_info;
   FREE(shader->primitive_lengths);
   shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned));


#ifdef HAVE_LLVM
   if (draw_get_option_use_llvm()) {
      shader->gs_output = output_verts->verts;
      if (max_out_prims > shader->max_out_prims) {
         unsigned i;
         if (shader->llvm_prim_lengths) {
            for (i = 0; i < shader->max_out_prims; ++i) {
               align_free(shader->llvm_prim_lengths[i]);
            }
            FREE(shader->llvm_prim_lengths);
         }

         shader->llvm_prim_lengths = MALLOC(max_out_prims * sizeof(unsigned*));
         for (i = 0; i < max_out_prims; ++i) {
            int vector_size = shader->vector_length * sizeof(unsigned);
            shader->llvm_prim_lengths[i] =
               align_malloc(vector_size, vector_size);
         }

         shader->max_out_prims = max_out_prims;
      }
      shader->jit_context->prim_lengths = shader->llvm_prim_lengths;
      shader->jit_context->emitted_vertices = shader->llvm_emitted_vertices;
      shader->jit_context->emitted_prims = shader->llvm_emitted_primitives;
   }
#endif

   shader->prepare(shader, constants, constants_size);

   if (input_prim->linear)
      gs_run(shader, input_prim, input_verts,
             output_prims, output_verts);
   else
      gs_run_elts(shader, input_prim, input_verts,
                  output_prims, output_verts);

   /* Flush the remaining primitives. Will happen if
    * num_input_primitives % 4 != 0
    */
   if (shader->fetched_prim_count > 0) {
      gs_flush(shader);
   }

   debug_assert(shader->fetched_prim_count == 0);

   /* Update prim_info:
    */
   output_prims->linear = TRUE;
   output_prims->elts = NULL;
   output_prims->start = 0;
   output_prims->count = shader->emitted_vertices;
   output_prims->prim = shader->output_primitive;
   output_prims->flags = 0x0;
   output_prims->primitive_lengths = shader->primitive_lengths;
   output_prims->primitive_count = shader->emitted_primitives;
   output_verts->count = shader->emitted_vertices;

   if (shader->draw->collect_statistics) {
      unsigned i;
      for (i = 0; i < shader->emitted_primitives; ++i) {
         shader->draw->statistics.gs_primitives +=
            u_decomposed_prims_for_vertices(shader->output_primitive,
                                            shader->primitive_lengths[i]);
      }
   }

#if 0
   debug_printf("GS finished, prims = %d, verts = %d\n",
                output_prims->primitive_count,
                output_verts->count);
#endif

   return shader->emitted_vertices;
}