Skip to content

RenderingDevice.texture_create does not respect LIMIT_MAX_TEXTURE_SIZE #93798

Closed
@Carbonyte

Description

@Carbonyte

Tested versions

  • Reproducible in: v4.2.1.stable.mono.official [b09f793], v4.3.beta2.mono.official [b75f048]

System information

Godot v4.2.1.stable.mono - Windows 10.0.19045 - Vulkan (Forward+) - dedicated Radeon RX 580 Series (Advanced Micro Devices, Inc.; 31.0.21912.14) - AMD Ryzen 5 3600 6-Core Processor (12 Threads)

Issue description

Calling texture_create with dimensions exceeding LIMIT_MAX_TEXTURE_SIZE_* does not produce an error, as expected. From within a shader, the texture size is reported as RDTextureFormat.width % LIMIT_MAX_TEXTURE_SIZE_*, though this may be undefined behavior.

Steps to reproduce

extends Node3D

var rd: RenderingDevice

func textureTest():
	var shaderSrc := RDShaderSource.new()
	shaderSrc.source_compute = """
	#version 450

	layout(set = 0, binding = 0, r32i) uniform restrict iimage1DArray test;

	layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
	void main() {
		imageStore(test, ivec2(0, 0), ivec4(imageSize(test).x));
		imageStore(test, ivec2(1, 0), ivec4(imageSize(test).y));
	}
	"""
	
	var shaderBytecode := rd.shader_compile_spirv_from_source(shaderSrc)
	var shader := rd.shader_create_from_spirv(shaderBytecode)
	var pipeline := rd.compute_pipeline_create(shader)
	
	var tf := RDTextureFormat.new()
	tf.format = RenderingDevice.DATA_FORMAT_R32_SINT
	tf.texture_type = RenderingDevice.TEXTURE_TYPE_1D_ARRAY
	tf.width = rd.limit_get(RenderingDevice.LIMIT_MAX_TEXTURE_SIZE_1D) + 2
	tf.height = 1
	# On my device the limit appears to be 4 times what is reported by limit_get
	tf.array_layers = rd.limit_get(RenderingDevice.LIMIT_MAX_TEXTURE_ARRAY_LAYERS) * 4 + 1
	tf.mipmaps = 1
	tf.usage_bits = (
		RenderingDevice.TEXTURE_USAGE_CAN_UPDATE_BIT |
		RenderingDevice.TEXTURE_USAGE_STORAGE_BIT |
		RenderingDevice.TEXTURE_USAGE_CAN_COPY_FROM_BIT |
		RenderingDevice.TEXTURE_USAGE_CPU_READ_BIT
	)
	var texture = rd.texture_create(tf, RDTextureView.new())
	
	var uniform := RDUniform.new()
	uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
	uniform.binding = 0
	uniform.add_id(texture)
	var uniformSet := rd.uniform_set_create([uniform], shader, 0)
	
	var computeList := rd.compute_list_begin()
	rd.compute_list_bind_compute_pipeline(computeList, pipeline)
	rd.compute_list_bind_uniform_set(computeList, uniformSet, 0)
	rd.compute_list_dispatch(computeList, 1, 1, 1)
	rd.compute_list_end()
	
	rd.submit()
	rd.sync()
	
	var bytes := rd.texture_get_data(texture, 0)
	print("Got ", bytes.size() / 4, " pixels")
	var realWidth := bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24)
	var realLayers := bytes[4] + (bytes[5] << 8) + (bytes[6] << 16) + (bytes[7] << 24)
	print("Shader sees width=", realWidth, ", expected ", tf.width)
	print("Shader sees layers=", realLayers, ", expected ", tf.array_layers)
	
	rd.free_rid(shader)
	rd.free_rid(texture)

func _ready():
	rd = RenderingServer.create_local_rendering_device()
	
	textureTest()

Minimal reproduction project (MRP)

repro.zip

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions