Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Direct3D 12 debug layer crashes when updating a texture used in a previous draw call on the same frame #12544

Closed
nmlgc opened this issue Mar 14, 2025 · 7 comments · Fixed by #12591 or #12597
Milestone

Comments

@nmlgc
Copy link

nmlgc commented Mar 14, 2025

Discovered thanks to this (accidental?) change in the recent SDL_SCALEMODE_PIXELART implementation:

createDebug = true;//SDL_GetHintBoolean(SDL_HINT_RENDER_DIRECT3D11_DEBUG, false);

A minimal example:

#include <SDL3/SDL.h>
#include <stdint.h>

static const unsigned int W = 256;
static const unsigned int H = 256;

typedef struct {
	uint8_t b, g, r, a;
} argb_t;

argb_t temp[256 * 128];

void test(SDL_Renderer *renderer, SDL_Texture *tex, int y, uint8_t b, uint8_t r)
{
	const argb_t color = { b, 0, r, 0xFF };
	const SDL_Rect rect = { 0, y, W, (H / 2) };
	const SDL_FRect frect = { 0, y, W, (H / 2) };

	for(size_t i = 0; i < (sizeof(temp) / sizeof(temp[0])); i++) {
		temp[i] = color;
	}
	SDL_UpdateTexture(tex, &rect, temp, (W * sizeof(argb_t)));
	SDL_RenderTexture(renderer, tex, &frect, &frect);
}

int main(void)
{
	SDL_Window *window = NULL;
	SDL_Renderer *renderer = NULL;

	SDL_Init(SDL_INIT_VIDEO);
	SDL_SetHint(SDL_HINT_RENDER_DRIVER, "direct3d12");
	SDL_SetHint(SDL_HINT_RENDER_DIRECT3D11_DEBUG, "1");
	SDL_CreateWindowAndRenderer("Test", W, H, 0, &window, &renderer);

	SDL_Texture *tex = SDL_CreateTexture(
		renderer,
		SDL_PIXELFORMAT_ARGB8888,
		SDL_TEXTUREACCESS_STREAMING,
		W,
		H
	);

	test(renderer, tex, 0, 0xFF, 0);
	test(renderer, tex, (H / 2), 0, 0xFF);

	SDL_RenderPresent(renderer);
	SDL_Delay(5000);

	SDL_Quit();

	return 0;
}

This code crashes with the following error:

D3D12 ERROR: ID3D12CommandList::DrawInstanced: Resource(0x0A2902F8:'Unnamed ID3D12Resource Object') (subresource : 0) is bound as DATA_STATIC_WHILE_SET_AT_EXECUTE on this command list, and had a change to a writable state, which indicates a data change, before this Draw/Dispatch call. But it is required to be rebound to the command list before the next (this) Draw/Dispatch call. [ EXECUTION ERROR #1003: DATA_STATIC_WHILE_SET_AT_EXECUTE_DESCRIPTOR_INVALID_DATA_CHANGE]
D3D12: **BREAK** enabled for the previous message, which was: [ ERROR EXECUTION #1003: DATA_STATIC_WHILE_SET_AT_EXECUTE_DESCRIPTOR_INVALID_DATA_CHANGE ]

It works on every other renderer, including the Direct3D 11 one with debug layers enabled.

@slouken
Copy link
Collaborator

slouken commented Mar 15, 2025

@thatcosmonaut, what's the proper fix here?

@slouken slouken added this to the 3.2.10 milestone Mar 15, 2025
@thatcosmonaut
Copy link
Collaborator

The texture is being updated every frame, but it isn't necessarily done being used by the previous submission. This is why the cycle concept exists in SDL GPU.

@slouken slouken modified the milestones: 3.2.10, 3.x Mar 15, 2025
@slouken
Copy link
Collaborator

slouken commented Mar 15, 2025

Out of curiosity, is there a particular reason you're using the D3D12 renderer?

@nmlgc
Copy link
Author

nmlgc commented Mar 16, 2025

I let users select between all of them, because you can never know which of them might be broken on any given system, and which one performs best.

@slouken
Copy link
Collaborator

slouken commented Mar 16, 2025

Makes sense. Thanks for the feedback and the bug report!

@slouken
Copy link
Collaborator

slouken commented Mar 21, 2025

I was able to reproduce this on AMD hardware, but not on NVIDIA hardware.

@slouken
Copy link
Collaborator

slouken commented Mar 21, 2025

Fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants