• Advertisement
Sign in to follow this  

software resterizing - shaders

This topic is 3733 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Currently, I have a software rasterizer working, and i've been optimising it with sse code. Now I've got down interpolation functions down to a nice speed, now my biggest slow down is actually the shader code I call on each pixel. I have something like this for each pixel shader:
virtual void Apply(const ParameterData* parameter, const PixelInput* input, PixelOutput* output)
	{
		register ShaderColourTexturePixelInput* in = (ShaderColourTexturePixelInput*)input;
		output->colour = in->colour; //* texture look up
	}

My guess on why it takes so long is that this cant be inlined so i cope a massive function call over head. Now I want to try to eradicate this function call some how if I can. I've been thinking if some nasty hackery using defines for example I currently do this:
RasterizeTriangle(verts[3])
{
  bunch of loops here iterating over each pixel
  {
    pixelShader->Apply(...);
  }
}

now im thinking something nasty: so my pixel shader now handles complete rasterization:
virtual void Apply(verts[3])
{
   RASTERIZE_BEGIN(verts)

register ShaderColourTexturePixelInput* in = (ShaderColourTexturePixelInput*)input;
		output->colour = in->colour; //* texture look up
   
   RASTERIZE_END(verts)
}

is there a better solution? as these macros are going to be massive and nasty! maybe some template magic?

Share this post


Link to post
Share on other sites
Advertisement
I wrote a software rasterizer/renderer myself for the gp2x. It uses fixed point arithmetic for everything. Initially I also had a pixel shader class with a virtual function which was called for each pixel to be shaded but that was way to much overhead (>30%). I found a nice solution using templates which completely avoids the virtual function call overhead and also allows full inlining of the pixel shader into the rasterization function.

You can find the link to my software rasterizer in my signature.

Share this post


Link to post
Share on other sites
okay, i see whats going down there, cant work out how to get it going in my own app though :-/

so I have this:


class SoftwareDevice
{

typedef void (SoftwareDevice::*RasterizeFunc)(PixelInput* pixelInput[3], PixelInput* interpolators[6], unsigned int pixelInputSize, SoftwarePixelShader* pixelShader, ParameterData* parameterData);


template <class T>
void Rasterize(PixelInput* pixelInput[3], PixelInput* interpolators[6], unsigned int pixelInputSize, SoftwarePixelShader* pixelShader, ParameterData* parameterData);
}

class SoftwarePixelShader
{
SoftwarePixelShader()
{
rasterizeFunc = &SoftwareDevice::Rasterize<SoftwarePixelShader>;
}

SoftwareDevice::RasterizeFunc rasterizeFunc;
}





then in:


SoftwareDevice::Draw()
{
// attempt to call the function on this device
RasterizeFunc rasterizeFunc = pixelShader->rasterizeFunc;
*this.*rasterizeFunc(pixelInput, interpolators, pixelInputSize, pixelShader, parameterData);
}





the last line says:
error C2064: term does not evaluate to a function taking 5 arguments

any ideas what im doing wrong?

Share this post


Link to post
Share on other sites
I think this is the problem:

*this.*rasterizeFunc(pixelInput, interpolators, pixelInputSize, pixelShader, parameterData);

you might have to enclose the first part into parenthesis: (*this.*rasterizeFunc)(...)

Or maybe this way: (this->*rasterizeFunc)(...)

But the templated function in your SoftwareDevice class does not even use the template type T and seems kind of wrong to me. At least my approach does not look anything like it.

My approach is:


class Rasterizer {
public:
template <class PixelShader>
void set_pixel_shader()
{
triangle_func = &Rasterizer::triangle_template<PixelShader>;
}

void draw_triangle(<signature>)
{
triangle_func(<signature>);
}

private:
void (Rasterizer::*triangle_func)(<signature>);

template <class PixelShader>
void triangle_template(<signature>)
{
// rasterize triangle and call the static functions from the
// PixelShader class like PixelShader::shade(<per_pixel_parameters>);
}
};

class MyPixelShader {
public:
// NOTE: this is a static function
static void shade(<per_pixel_parameters>)
{
// do the pixel shading here
}
};

// main program

// this will set the pixel shader at compile time
Rasterizer r;
r.set_pixel_shader<MyPixelShader>();
r.draw_triangle(<signature>);



Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement