Sign in to follow this  
jdub

Texture Renders Incorrectly in Application but Perfectly fine in VS2013's Graphics Debugger

Recommended Posts

jdub    459

I am building an application that rasterizes (on the CPU) and renders 2D triangles.  In order to do this, I create a texture to hold the 2D triangles and then render it on-screen on a textured quad.  The issue is that, the triangle renders incorrectly when rendered while the application is running.  However, when I capture a frame inside the VS2013's graphics debugger, the resultant frame is rendered with the triangle appearing as I would expect it to be.  Here is code for how I create the texture holding the triangle:

struct Pixel
{
char r, g, b, a;
};

....

HRESULT res;
D3D11_TEXTURE2D_DESC texture_desc;
D3D11_SUBRESOURCE_DATA initial_data;
D3D11_SHADER_RESOURCE_VIEW_DESC SRV_desc;
Pixel default_color;

this->raw_data = (char *)malloc(this->image_width*this->image_height*sizeof(Pixel));
default_color.r = 0;
default_color.g = 0;
default_color.b = 0;
default_color.a = 255;

texture_desc.ArraySize = 1;
texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texture_desc.Width = this->image_width;
texture_desc.Height = this->image_height;
texture_desc.MipLevels = 1;
texture_desc.MiscFlags = 0;
texture_desc.SampleDesc.Count = 1; 
texture_desc.SampleDesc.Quality = 0;
texture_desc.Usage = D3D11_USAGE_DYNAMIC;

initial_data.pSysMem = this->raw_data;
initial_data.SysMemPitch = this->image_width * sizeof(Pixel);
initial_data.SysMemSlicePitch = 0;
	
SRV_desc.Texture2D.MipLevels = 1;
SRV_desc.Texture2D.MostDetailedMip = 0;
SRV_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
SRV_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;

for (int i = 0; i < this->image_height; i++)
{
	for (int j = 0; j < this->image_width; j++)
	{
		memcpy(&this->raw_data[i*this->image_width*sizeof(Pixel) + j*sizeof(Pixel)], &default_color, sizeof(Pixel));
	}
}

if (FAILED(res = this->renderer->GetDevice()->CreateTexture2D(&texture_desc, &initial_data, &this->texture)))
{
	return false;
}

if (FAILED(res = this->renderer->GetDevice()->CreateShaderResourceView(this->texture, &SRV_desc, &this->texture_SRV)))
{
	return false;
}

And here is where the quad is rendered:

D3D11_MAPPED_SUBRESOURCE mapped_subresource;
ID3D11Buffer *vBuffs = {this->quad_v_buffer};
UINT strides[] = {sizeof(TexturedVertex)};
UINT offsets[] = {0};
ID3D11SamplerState *sampler_states = { this->renderer->GetSamplerState() };
ID3D11ShaderResourceView *textureSRVs = { this->texture_SRV };

HRESULT res = this->renderer->GetDeviceContext()->Map(this->texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_subresource);
memcpy(mapped_subresource.pData, this->raw_data, this->image_width*this->image_height*sizeof(Pixel));
this->renderer->GetDeviceContext()->Unmap(this->texture, 0);

this->renderer->BindShader(SHADER_TYPE_TEXTURE);
this->renderer->SetTransform(TRANSFORM_WORLD, Matrix::Identity());
this->renderer->SetTransform(TRANSFORM_VIEW, Matrix::Identity());
this->renderer->SetTransform(TRANSFORM_PROJECTION, Matrix::Identity());

this->renderer->GetDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
this->renderer->GetDeviceContext()->IASetVertexBuffers(0, 1, &vBuffs, strides, offsets);
	
this->renderer->GetDeviceContext()->PSSetShaderResources(0, 1, &textureSRVs);

this->renderer->SetCullMode(D3D11_CULL_NONE);

this->renderer->GetDeviceContext()->Draw(6, 0);

I should also add that the previous code works absolutely fine (renders a textured quad) when I provide a texture that I load from disk.

 

Attached are images of how the quad renders 2 triangles correctly (in the graphics debugger) and incorrectly (on the application window).[attachment=25657:triangle_error.jpg]

[attachment=25656:triangle_correct.jpg]

Edited by jdub

Share this post


Link to post
Share on other sites
ankhd    2304
Hi. May be you are not zeroing out the structure like memset on texture description and other structure. Do that and see.
The debug builds validate all members and release don't.

Share this post


Link to post
Share on other sites
jdub    459

Thanks for the response.  Perhaps I didn't clarify but the Application renders incorrectly while running in debug mode.  However, when a frame is captured inside the graphics debugger, the frame renders as it should.  

Share this post


Link to post
Share on other sites
Adam_42    3629

HRESULT res = this->renderer->GetDeviceContext()->Map(this->texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_subresource);
memcpy(mapped_subresource.pData, this->raw_data, this->image_width*this->image_height*sizeof(Pixel));
this->renderer->GetDeviceContext()->Unmap(this->texture, 0);

 

This is almost certainly where it's going wrong. You're ignoring the pitch value in the mapped_subresource, and it just happens to work correctly when using the debugger.

Share this post


Link to post
Share on other sites
Buckeye    10747

As Adam_42 mentions, the Map call looks suspicious. In addition, is there a reason you call Map/Unmap after you've already created an SRV from the texture?

Share this post


Link to post
Share on other sites
jdub    459

 

 

As Adam_42 mentions, the Map call looks suspicious. In addition, is there a reason you call Map/Unmap after you've already created an SRV from the texture?

 

This is for a school project where the goal is to rasterize triangles.  Thus, the contents of the texture "back buffer" could change so I would rather Map/Unmap it than create a new texture every time I need to draw.

 

It turns out that the Map/Unmap is indeed the culprit.  I was creating the texture as a size that isn't memory aligned (1000*1000) so DirectX pads the texture to make it be aligned.  I wasn't accounting for the extra padding while writing texture data.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this