Hi Brian,

I created a smallest possible test case to reproduce the segfault, as attached. Please see file header on how I compile it. vs and fs both needs to be checked to avoid the segfault.

If I replace the screen creation part to use swrast or r600, they both work fine.

Thanks.

Vic

On 03/06/2012 07:44 AM, Brian Paul wrote:
On 03/03/2012 04:17 AM, Vic Lee wrote:
This patch fix segfault if an application clears a render target
before setting any vertex or fragment shaders, which is a legal
situation.

I can't seem to trigger this problem with a test program. Can you post a
test case?

The first part of your patch looks OK but I don't see why the second
part is needed. We already check svga->curr.fs before dereffing the
pointer.

-Brian


/*
put this file under src/gallium and compile with:

gcc -Wall -g -O0 -o test -DDEBUG -I/usr/include/libdrm -I./include -I./auxiliary -I./winsys -I./drivers test.c \
./winsys/svga/drm/libsvgadrm.a ./winsys/sw/wrapper/libwsw.a ./drivers/svga/libsvga.a ./auxiliary/libgallium.a \
`llvm-config --libs` -lstdc++ -lpthread -ldrm -lm -ldl
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xf86drm.h>
#include "pipe/p_compiler.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "util/u_debug.h"
#include "target-helpers/inline_debug_helper.h"
#include "svga/drm/svga_drm_public.h"
#include "svga/svga_public.h"

#define SVGA_PCI_BUSID "PCI:0000:00:0f.0"

int main(int argc, char *argv[])
{
	struct pipe_screen *screen;
	struct pipe_context *pipe;
	struct pipe_framebuffer_state framebuffer;
	int fd;
	int newlyopened;
	struct svga_winsys_screen *sws;
	struct pipe_resource resource;
	struct pipe_resource *rendertarget;
	struct pipe_surface surface;
	struct pipe_rasterizer_state rasterizer;
	void *rs;

	float color[] = { 1.0f, 0.4f, 0.4f, 1.0f };

	fd = drmOpenOnce(NULL, SVGA_PCI_BUSID, &newlyopened);
	if (fd < 0)
	{
		printf("drmOpenOnce failed\n");
		return 1;
	}

	sws = svga_drm_winsys_screen_create(fd);
	if (!sws)
	{
		printf("svga_drm_winsys_screen_create failed\n");
		return 1;
	}

	screen = svga_screen_create(sws);
	if (!screen)
	{
		printf("svga_screen_create failed\n");
		return 1;
	}
	
	pipe = screen->context_create(screen, NULL);
	if (!pipe)
	{
		printf("context_create failed\n");
		return 1;
	}

	memset(&resource, 0, sizeof(resource));
	resource.target = PIPE_TEXTURE_2D;
	resource.format = PIPE_FORMAT_B8G8R8A8_UNORM;
	resource.bind = PIPE_BIND_RENDER_TARGET;
	resource.width0 = 300;
	resource.height0 = 300;
	resource.depth0 = 1;
	resource.array_size = 1;
	resource.last_level = 0;
	resource.nr_samples = 1;
	rendertarget = (struct pipe_resource *) screen->resource_create(screen, &resource);

	memset(&surface, 0, sizeof(surface));
	surface.format = rendertarget->format;
	surface.usage = PIPE_BIND_RENDER_TARGET;

	memset(&framebuffer, 0, sizeof(framebuffer));
	framebuffer.width = rendertarget->width0;
	framebuffer.height = rendertarget->height0;
	framebuffer.cbufs[0] = pipe->create_surface(pipe, rendertarget, &surface);
	framebuffer.nr_cbufs = 1;

	pipe->set_framebuffer_state(pipe, &framebuffer);

	/* the driver crash if rasterizer state is not set before we call clear! */
	memset(&rasterizer, 0, sizeof(rasterizer));
	rs = pipe->create_rasterizer_state(pipe, &rasterizer);
	pipe->bind_rasterizer_state(pipe, rs);

	pipe->clear(pipe, PIPE_CLEAR_COLOR, (const union pipe_color_union *)color, 0, 1);
	pipe->flush(pipe, NULL);

	debug_dump_surface_bmp(pipe, "result.bmp", framebuffer.cbufs[0]);

	return 0;
}

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to